aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornovenary <streetwalkermc@gmail.com>2023-03-11 14:51:52 +0200
committerSimon Ser <contact@emersion.fr>2023-05-04 18:05:00 +0000
commitd7917d20762f85d58e5d8db7f19aec6be3e9ed56 (patch)
tree7a7bd0d7a260708edb010c878e82f2ab86a51790
parent2827ec6b7b4ba45d3911258cd7a383eccd722c28 (diff)
xwayland: allow compositor to set withdrawn state
-rw-r--r--include/wlr/xwayland/xwayland.h4
-rw-r--r--xwayland/xwm.c45
2 files changed, 35 insertions, 14 deletions
diff --git a/include/wlr/xwayland/xwayland.h b/include/wlr/xwayland/xwayland.h
index c1dbc339..a8983f1f 100644
--- a/include/wlr/xwayland/xwayland.h
+++ b/include/wlr/xwayland/xwayland.h
@@ -136,6 +136,7 @@ struct wlr_xwayland_surface {
bool fullscreen;
bool maximized_vert, maximized_horz;
bool minimized;
+ bool withdrawn;
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_set_withdrawn(struct wlr_xwayland_surface *surface,
+ bool withdrawn);
+
void wlr_xwayland_surface_set_minimized(struct wlr_xwayland_surface *surface,
bool minimized);
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
index 5f857f24..dbca0038 100644
--- a/xwayland/xwm.c
+++ b/xwayland/xwm.c
@@ -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) {
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];
size_t i = 0;
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,
- int32_t state) {
+static void xsurface_set_wm_state(struct wlr_xwayland_surface *xsurface) {
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_PROP_MODE_REPLACE,
@@ -1097,9 +1112,7 @@ static void xwm_handle_map_request(struct wlr_xwm *xwm,
return;
}
- xsurface_set_wm_state(xsurface, XCB_ICCCM_WM_STATE_NORMAL);
- xsurface_set_net_wm_state(xsurface);
-
+ wlr_xwayland_surface_set_withdrawn(xsurface, false);
wlr_xwayland_surface_restack(xsurface, NULL, XCB_STACK_MODE_BELOW);
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);
- 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,
@@ -2223,16 +2238,18 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
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,
bool minimized) {
surface->minimized = minimized;
-
- 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_wm_state(surface);
xsurface_set_net_wm_state(surface);
xcb_flush(surface->xwm->xcb_conn);
}