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,