From 7d90cd055d82ef8368318433ec9fa9bfc271a3da Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Fri, 17 Feb 2023 08:25:39 -0500 Subject: [PATCH] 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() --- xwayland/xwm.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) 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); }