aboutsummaryrefslogtreecommitdiff
path: root/xwayland
diff options
context:
space:
mode:
authorJohn Lindgren <john@jlindgren.net>2023-02-17 08:25:39 -0500
committerIsaac Freund <mail@isaacfreund.com>2023-02-21 09:32:06 +0000
commit7d90cd055d82ef8368318433ec9fa9bfc271a3da (patch)
tree121b02822fce5c223368954eda336cf59e6394a3 /xwayland
parent3ef9f9128306cac549a99a3e844b3e55f9381279 (diff)
xwayland: Send synthetic ConfigureNotify per ICCCM 4.1.5
X11 clients expect a ConfigureNotify after a ConfigureRequest. If the compositor/window manager chooses not to honor the request (e.g. due to the window being maximized), XWayland will not send a "real" ConfigureNotify event and the window manager is expected to send a synthetic event instead. Otherwise, the X11 client is left waiting and may not repaint its window properly. For comparison, see Openbox's client_configure() or Weston's weston_wm_window_send_configure_notify(). v2: Move logic to wlr_xwayland_surface_configure()
Diffstat (limited to 'xwayland')
-rw-r--r--xwayland/xwm.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
index 11a7d9aa..5a36dc21 100644
--- a/xwayland/xwm.c
+++ b/xwayland/xwm.c
@@ -1760,6 +1760,9 @@ void wlr_xwayland_surface_activate(struct wlr_xwayland_surface *xsurface,
void wlr_xwayland_surface_configure(struct wlr_xwayland_surface *xsurface,
int16_t x, int16_t y, uint16_t width, uint16_t height) {
+ int old_w = xsurface->width;
+ int old_h = xsurface->height;
+
xsurface->x = x;
xsurface->y = y;
xsurface->width = width;
@@ -1771,6 +1774,28 @@ void wlr_xwayland_surface_configure(struct wlr_xwayland_surface *xsurface,
XCB_CONFIG_WINDOW_BORDER_WIDTH;
uint32_t values[] = {x, y, width, height, 0};
xcb_configure_window(xwm->xcb_conn, xsurface->window_id, mask, values);
+
+ // If the window size did not change, then we cannot rely on
+ // the X server to generate a ConfigureNotify event. Instead,
+ // we are supposed to send a synthetic event. See ICCCM part
+ // 4.1.5. But we ignore override-redirect windows as ICCCM does
+ // not apply to them.
+ if (width == old_w && height == old_h && !xsurface->override_redirect) {
+ xcb_configure_notify_event_t configure_notify = {
+ .response_type = XCB_CONFIGURE_NOTIFY,
+ .event = xsurface->window_id,
+ .window = xsurface->window_id,
+ .x = x,
+ .y = y,
+ .width = width,
+ .height = height,
+ };
+
+ xcb_send_event(xwm->xcb_conn, 0, xsurface->window_id,
+ XCB_EVENT_MASK_STRUCTURE_NOTIFY,
+ (const char *)&configure_notify);
+ }
+
xcb_flush(xwm->xcb_conn);
}