diff options
author | John Lindgren <john@jlindgren.net> | 2023-02-17 08:25:39 -0500 |
---|---|---|
committer | Isaac Freund <mail@isaacfreund.com> | 2023-02-21 09:32:06 +0000 |
commit | 7d90cd055d82ef8368318433ec9fa9bfc271a3da (patch) | |
tree | 121b02822fce5c223368954eda336cf59e6394a3 | |
parent | 3ef9f9128306cac549a99a3e844b3e55f9381279 (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()
-rw-r--r-- | xwayland/xwm.c | 25 |
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); } |