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 <derek.foreman@collabora.com>
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user