xwayland: allow compositor to set withdrawn state

This commit is contained in:
novenary 2023-03-11 14:51:52 +02:00 committed by Simon Ser
parent 2827ec6b7b
commit d7917d2076
2 changed files with 35 additions and 14 deletions

View file

@ -136,6 +136,7 @@ struct wlr_xwayland_surface {
bool fullscreen; bool fullscreen;
bool maximized_vert, maximized_horz; bool maximized_vert, maximized_horz;
bool minimized; bool minimized;
bool withdrawn;
bool has_alpha; bool has_alpha;
@ -226,6 +227,9 @@ void wlr_xwayland_surface_configure(struct wlr_xwayland_surface *surface,
void wlr_xwayland_surface_close(struct wlr_xwayland_surface *surface); void wlr_xwayland_surface_close(struct wlr_xwayland_surface *surface);
void wlr_xwayland_surface_set_withdrawn(struct wlr_xwayland_surface *surface,
bool withdrawn);
void wlr_xwayland_surface_set_minimized(struct wlr_xwayland_surface *surface, void wlr_xwayland_surface_set_minimized(struct wlr_xwayland_surface *surface,
bool minimized); bool minimized);

View file

@ -352,6 +352,14 @@ static void xwm_surface_activate(struct wlr_xwm *xwm,
static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) { static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) {
struct wlr_xwm *xwm = xsurface->xwm; struct wlr_xwm *xwm = xsurface->xwm;
// EWMH says _NET_WM_STATE should be unset if the window is withdrawn
if (xsurface->withdrawn) {
xcb_delete_property(xwm->xcb_conn,
xsurface->window_id,
xwm->atoms[NET_WM_STATE]);
return;
}
uint32_t property[6]; uint32_t property[6];
size_t i = 0; size_t i = 0;
if (xsurface->modal) { if (xsurface->modal) {
@ -1035,10 +1043,17 @@ static void xwm_handle_configure_notify(struct wlr_xwm *xwm,
} }
} }
static void xsurface_set_wm_state(struct wlr_xwayland_surface *xsurface, static void xsurface_set_wm_state(struct wlr_xwayland_surface *xsurface) {
int32_t state) {
struct wlr_xwm *xwm = xsurface->xwm; struct wlr_xwm *xwm = xsurface->xwm;
uint32_t property[] = { state, XCB_WINDOW_NONE }; uint32_t property[] = { XCB_ICCCM_WM_STATE_NORMAL, XCB_WINDOW_NONE };
if (xsurface->withdrawn) {
property[0] = XCB_ICCCM_WM_STATE_WITHDRAWN;
} else if (xsurface->minimized) {
property[0] = XCB_ICCCM_WM_STATE_ICONIC;
} else {
property[0] = XCB_ICCCM_WM_STATE_NORMAL;
}
xcb_change_property(xwm->xcb_conn, xcb_change_property(xwm->xcb_conn,
XCB_PROP_MODE_REPLACE, XCB_PROP_MODE_REPLACE,
@ -1097,9 +1112,7 @@ static void xwm_handle_map_request(struct wlr_xwm *xwm,
return; return;
} }
xsurface_set_wm_state(xsurface, XCB_ICCCM_WM_STATE_NORMAL); wlr_xwayland_surface_set_withdrawn(xsurface, false);
xsurface_set_net_wm_state(xsurface);
wlr_xwayland_surface_restack(xsurface, NULL, XCB_STACK_MODE_BELOW); wlr_xwayland_surface_restack(xsurface, NULL, XCB_STACK_MODE_BELOW);
xcb_map_window(xwm->xcb_conn, ev->window); xcb_map_window(xwm->xcb_conn, ev->window);
} }
@ -1126,7 +1139,9 @@ static void xwm_handle_unmap_notify(struct wlr_xwm *xwm,
xwayland_surface_dissociate(xsurface); xwayland_surface_dissociate(xsurface);
xsurface_set_wm_state(xsurface, XCB_ICCCM_WM_STATE_WITHDRAWN); if (!xsurface->override_redirect) {
wlr_xwayland_surface_set_withdrawn(xsurface, true);
}
} }
static void xwm_handle_property_notify(struct wlr_xwm *xwm, static void xwm_handle_property_notify(struct wlr_xwm *xwm,
@ -2223,16 +2238,18 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
return xwm; return xwm;
} }
void wlr_xwayland_surface_set_withdrawn(struct wlr_xwayland_surface *surface,
bool withdrawn) {
surface->withdrawn = withdrawn;
xsurface_set_wm_state(surface);
xsurface_set_net_wm_state(surface);
xcb_flush(surface->xwm->xcb_conn);
}
void wlr_xwayland_surface_set_minimized(struct wlr_xwayland_surface *surface, void wlr_xwayland_surface_set_minimized(struct wlr_xwayland_surface *surface,
bool minimized) { bool minimized) {
surface->minimized = minimized; surface->minimized = minimized;
xsurface_set_wm_state(surface);
if (minimized) {
xsurface_set_wm_state(surface, XCB_ICCCM_WM_STATE_ICONIC);
} else {
xsurface_set_wm_state(surface, XCB_ICCCM_WM_STATE_NORMAL);
}
xsurface_set_net_wm_state(surface); xsurface_set_net_wm_state(surface);
xcb_flush(surface->xwm->xcb_conn); xcb_flush(surface->xwm->xcb_conn);
} }