From af5161870831ccf576c31afe26a4b471f4fa8a1e Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Wed, 22 Jun 2022 12:05:23 -0500 Subject: [PATCH] xwayland/window-manager: Add support for _NET_FRAME_EXTENTS https://specifications.freedesktop.org/wm-spec/1.4/ar01s05.html says "The Window Manager MUST set _NET_FRAME_EXTENTS to the extents of the window's frame", so this is probably something we should be doing. Some programs (such as some versions of Firefox) expect this to be present, and will render popups in wrong locations if it's not. Signed-off-by: Derek Foreman --- shared/xcb-xwayland.c | 1 + shared/xcb-xwayland.h | 1 + xwayland/window-manager.c | 44 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/shared/xcb-xwayland.c b/shared/xcb-xwayland.c index 737c82a5..d72a15a9 100644 --- a/shared/xcb-xwayland.c +++ b/shared/xcb-xwayland.c @@ -78,6 +78,7 @@ x11_get_atoms(xcb_connection_t *connection, struct atom_x11 *atom) { "WM_S0", F(wm_s0) }, { "WM_CLIENT_MACHINE", F(wm_client_machine) }, { "WM_CHANGE_STATE", F(wm_change_state) }, + { "_NET_FRAME_EXTENTS", F(net_frame_extents) }, { "_NET_WM_CM_S0", F(net_wm_cm_s0) }, { "_NET_WM_NAME", F(net_wm_name) }, { "_NET_WM_PID", F(net_wm_pid) }, diff --git a/shared/xcb-xwayland.h b/shared/xcb-xwayland.h index 7b233ede..8157240c 100644 --- a/shared/xcb-xwayland.h +++ b/shared/xcb-xwayland.h @@ -40,6 +40,7 @@ struct atom_x11 { xcb_atom_t wm_s0; xcb_atom_t wm_client_machine; xcb_atom_t wm_change_state; + xcb_atom_t net_frame_extents; xcb_atom_t net_wm_cm_s0; xcb_atom_t net_wm_name; xcb_atom_t net_wm_pid; diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index c75e0102..0833b617 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -174,6 +174,10 @@ struct weston_wm_window { struct wm_size_hints size_hints; struct motif_wm_hints motif_hints; struct wl_list link; + int decor_top; + int decor_bottom; + int decor_left; + int decor_right; }; static void @@ -1022,6 +1026,38 @@ weston_wm_window_set_wm_state(struct weston_wm_window *window, int32_t state) 2, property); } +static void +weston_wm_window_set_net_frame_extents(struct weston_wm_window *window) +{ + struct weston_wm *wm = window->wm; + uint32_t property[4]; + int top = 0, bottom = 0, left = 0, right = 0; + + if (!window->fullscreen) + frame_decoration_sizes(window->frame, &top, &bottom, &left, &right); + + if (window->decor_top == top && window->decor_bottom == bottom && + window->decor_left == left && window->decor_right == right) + return; + + window->decor_top = top; + window->decor_bottom = bottom; + window->decor_left = left; + window->decor_right = right; + + property[0] = left; + property[1] = right; + property[2] = top; + property[3] = bottom; + xcb_change_property(wm->conn, + XCB_PROP_MODE_REPLACE, + window->id, + wm->atom.net_frame_extents, + XCB_ATOM_CARDINAL, + 32, /* format */ + 4, property); +} + static void weston_wm_window_set_net_wm_state(struct weston_wm_window *window) { @@ -1362,6 +1398,7 @@ weston_wm_window_do_repaint(void *data) weston_wm_window_read_properties(window); weston_wm_window_draw_decoration(window); + weston_wm_window_set_net_frame_extents(window); weston_wm_window_set_pending_state(window); weston_wm_window_set_allow_commits(window, true); } @@ -1498,6 +1535,10 @@ weston_wm_window_create(struct weston_wm *wm, window->pos_dirty = false; window->map_request_x = INT_MIN; /* out of range for valid positions */ window->map_request_y = INT_MIN; /* out of range for valid positions */ + window->decor_top = -1; + window->decor_bottom = -1; + window->decor_left = -1; + window->decor_right = -1; weston_output_weak_ref_init(&window->legacy_fullscreen_output); geometry_reply = xcb_get_geometry_reply(wm->conn, geometry_cookie, NULL); @@ -2507,7 +2548,7 @@ weston_wm_create(struct weston_xserver *wxs, int fd) struct wl_event_loop *loop; xcb_screen_iterator_t s; uint32_t values[1]; - xcb_atom_t supported[6]; + xcb_atom_t supported[7]; wm = zalloc(sizeof *wm); if (wm == NULL) @@ -2561,6 +2602,7 @@ weston_wm_create(struct weston_xserver *wxs, int fd) supported[3] = wm->atom.net_wm_state_maximized_vert; supported[4] = wm->atom.net_wm_state_maximized_horz; supported[5] = wm->atom.net_active_window; + supported[6] = wm->atom.net_frame_extents; xcb_change_property(wm->conn, XCB_PROP_MODE_REPLACE, wm->screen->root,