From 2521fba37c396909eec6da88070ec9111aa2c507 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 12 Feb 2024 18:37:55 -0500 Subject: [PATCH] xwayland: add map_request signal For XWayland surfaces that start maximized, it's best to send an initial Configure event to set the size of the surface before mapping it. This reduces visual glitches since the application sees the correct maximized size when performing its initial layout and drawing. wlroots surfaces emit their first "map" event after the XWayland window has already been mapped and the first frame has been drawn & committed. This is too late to send the initial Configure event. So, add a new "map_request" event which is emitted immediately before telling XWayland to map the window. Compositors can connect to this event to send the initial Configure event to an XWayland app based on its requested maximized (or fullscreen) state. Compositors should not place anything visually on the screen at this point but rather wait until the "map" event as before. --- include/wlr/xwayland/xwayland.h | 2 ++ xwayland/xwm.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/wlr/xwayland/xwayland.h b/include/wlr/xwayland/xwayland.h index cb9e35f0..ff08796c 100644 --- a/include/wlr/xwayland/xwayland.h +++ b/include/wlr/xwayland/xwayland.h @@ -169,6 +169,8 @@ struct wlr_xwayland_surface { struct wl_signal set_strut_partial; struct wl_signal set_override_redirect; struct wl_signal set_geometry; + /* can be used to set initial maximized/fullscreen geometry */ + struct wl_signal map_request; struct wl_signal ping_timeout; } events; diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 2f80062a..6322b859 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -218,8 +218,9 @@ static struct wlr_xwayland_surface *xwayland_surface_create( wl_signal_init(&surface->events.set_decorations); wl_signal_init(&surface->events.set_strut_partial); wl_signal_init(&surface->events.set_override_redirect); - wl_signal_init(&surface->events.ping_timeout); wl_signal_init(&surface->events.set_geometry); + wl_signal_init(&surface->events.map_request); + wl_signal_init(&surface->events.ping_timeout); xcb_get_geometry_reply_t *geometry_reply = xcb_get_geometry_reply(xwm->xcb_conn, geometry_cookie, NULL); @@ -1123,6 +1124,7 @@ static void xwm_handle_map_request(struct wlr_xwm *xwm, return; } + wl_signal_emit_mutable(&xsurface->events.map_request, NULL); xcb_map_window(xwm->xcb_conn, ev->window); }