aboutsummaryrefslogtreecommitdiff
path: root/xwayland
diff options
context:
space:
mode:
authorJohn Lindgren <john@jlindgren.net>2022-11-09 16:09:43 -0500
committerJohn Lindgren <john@jlindgren.net>2023-02-13 12:57:20 -0500
commit068280201afdb8d87b1c624d115bed8866c6852e (patch)
tree62fcd3c498ecc61d63a62b737a30e5a8187f2990 /xwayland
parent23b7d22c6c04b4c86673d7d4bec5bf874a1f43f7 (diff)
xwayland: Read and publish _NET_WM_STRUT_PARTIAL property
This is needed for compositors that want to reserve space for XWayland panels. Such a feature can be useful in a "transitional" setup, where only the X11 window manager and compositor is replaced but other components of an X11 desktop environment are still used. This change simply reads the X11 property; the compositor is free to ignore it. Thus, compositors that don't want to support such a "transitional" feature are not impacted. v2: Update xwayland_surface_associate()
Diffstat (limited to 'xwayland')
-rw-r--r--xwayland/meson.build1
-rw-r--r--xwayland/xwm.c38
2 files changed, 39 insertions, 0 deletions
diff --git a/xwayland/meson.build b/xwayland/meson.build
index 5d22584b..08ad7a39 100644
--- a/xwayland/meson.build
+++ b/xwayland/meson.build
@@ -2,6 +2,7 @@ xwayland_libs = []
xwayland_required = [
'xcb',
'xcb-composite',
+ 'xcb-ewmh',
'xcb-icccm',
'xcb-render',
'xcb-res',
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
index de9a7a80..11a7d9aa 100644
--- a/xwayland/xwm.c
+++ b/xwayland/xwm.c
@@ -36,6 +36,7 @@ const char *const atom_map[ATOM_LAST] = {
[NET_WM_PID] = "_NET_WM_PID",
[NET_WM_NAME] = "_NET_WM_NAME",
[NET_WM_STATE] = "_NET_WM_STATE",
+ [NET_WM_STRUT_PARTIAL] = "_NET_WM_STRUT_PARTIAL",
[NET_WM_WINDOW_TYPE] = "_NET_WM_WINDOW_TYPE",
[WM_TAKE_FOCUS] = "WM_TAKE_FOCUS",
[WINDOW] = "WINDOW",
@@ -181,6 +182,7 @@ static struct wlr_xwayland_surface *xwayland_surface_create(
wl_signal_init(&surface->events.set_window_type);
wl_signal_init(&surface->events.set_hints);
wl_signal_init(&surface->events.set_decorations);
+ wl_signal_init(&surface->events.set_strut_partial);
wl_signal_init(&surface->events.set_override_redirect);
wl_signal_init(&surface->events.ping_timeout);
wl_signal_init(&surface->events.set_geometry);
@@ -440,6 +442,7 @@ static void xwayland_surface_destroy(struct wlr_xwayland_surface *xsurface) {
free(xsurface->startup_id);
free(xsurface->hints);
free(xsurface->size_hints);
+ free(xsurface->strut_partial);
free(xsurface);
}
@@ -761,6 +764,38 @@ static void read_surface_motif_hints(struct wlr_xwm *xwm,
}
}
+static void read_surface_strut_partial(struct wlr_xwm *xwm,
+ struct wlr_xwayland_surface *xsurface,
+ xcb_get_property_reply_t *reply) {
+ if (reply->type != XCB_ATOM_CARDINAL || reply->format != 32 ||
+ xcb_get_property_value_length(reply) !=
+ sizeof(xcb_ewmh_wm_strut_partial_t)) {
+ return;
+ }
+
+ free(xsurface->strut_partial);
+ xsurface->strut_partial = calloc(1, sizeof(xcb_ewmh_wm_strut_partial_t));
+ if (xsurface->strut_partial == NULL) {
+ return;
+ }
+ xcb_ewmh_get_wm_strut_partial_from_reply(xsurface->strut_partial, reply);
+
+ /*
+ * Translate right/bottom into root x/y coordinates here since
+ * the compositor is ignorant of X11 screen width/height.
+ *
+ * (This could result in an incorrect position if the X11 screen
+ * size changes but _NET_WM_STRUT_PARTIAL doesn't. It's probably
+ * not worth the additional code to fix this corner case.)
+ */
+ xsurface->strut_partial->right =
+ xwm->screen->width_in_pixels - xsurface->strut_partial->right;
+ xsurface->strut_partial->bottom =
+ xwm->screen->height_in_pixels - xsurface->strut_partial->bottom;
+
+ wl_signal_emit_mutable(&xsurface->events.set_strut_partial, xsurface);
+}
+
static void read_surface_net_wm_state(struct wlr_xwm *xwm,
struct wlr_xwayland_surface *xsurface,
xcb_get_property_reply_t *reply) {
@@ -827,6 +862,8 @@ static void read_surface_property(struct wlr_xwm *xwm,
read_surface_normal_hints(xwm, xsurface, reply);
} else if (property == xwm->atoms[MOTIF_WM_HINTS]) {
read_surface_motif_hints(xwm, xsurface, reply);
+ } else if (property == xwm->atoms[NET_WM_STRUT_PARTIAL]) {
+ read_surface_strut_partial(xwm, xsurface, reply);
} else if (property == xwm->atoms[WM_WINDOW_ROLE]) {
read_surface_role(xwm, xsurface, reply);
} else if (property == xwm->atoms[NET_STARTUP_ID]) {
@@ -910,6 +947,7 @@ static void xwayland_surface_associate(struct wlr_xwm *xwm,
xwm->atoms[MOTIF_WM_HINTS],
xwm->atoms[NET_STARTUP_ID],
xwm->atoms[NET_WM_STATE],
+ xwm->atoms[NET_WM_STRUT_PARTIAL],
xwm->atoms[NET_WM_WINDOW_TYPE],
xwm->atoms[NET_WM_NAME],
};