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.
This commit is contained in:
John Lindgren 2024-02-12 18:37:55 -05:00
parent 51c1e4aed1
commit 2521fba37c
2 changed files with 5 additions and 1 deletions

View file

@ -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;

View file

@ -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);
}