mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	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()
This commit is contained in:
		
							parent
							
								
									23b7d22c6c
								
							
						
					
					
						commit
						068280201a
					
				
					 4 changed files with 47 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -12,6 +12,7 @@
 | 
			
		|||
#include <stdbool.h>
 | 
			
		||||
#include <wayland-server-core.h>
 | 
			
		||||
#include <xcb/xcb.h>
 | 
			
		||||
#include <xcb/xcb_ewmh.h>
 | 
			
		||||
#include <xcb/xcb_icccm.h>
 | 
			
		||||
#include <wlr/util/addon.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -121,6 +122,11 @@ struct wlr_xwayland_surface {
 | 
			
		|||
	uint32_t decorations;
 | 
			
		||||
	xcb_icccm_wm_hints_t *hints;
 | 
			
		||||
	xcb_size_hints_t *size_hints;
 | 
			
		||||
	/*
 | 
			
		||||
	 * _NET_WM_STRUT_PARTIAL (used by e.g. XWayland panels;
 | 
			
		||||
	 * right/bottom are translated into root x/y coordinates)
 | 
			
		||||
	 */
 | 
			
		||||
	xcb_ewmh_wm_strut_partial_t *strut_partial;
 | 
			
		||||
 | 
			
		||||
	bool pinging;
 | 
			
		||||
	struct wl_event_source *ping_timer;
 | 
			
		||||
| 
						 | 
				
			
			@ -154,6 +160,7 @@ struct wlr_xwayland_surface {
 | 
			
		|||
		struct wl_signal set_window_type;
 | 
			
		||||
		struct wl_signal set_hints;
 | 
			
		||||
		struct wl_signal set_decorations;
 | 
			
		||||
		struct wl_signal set_strut_partial;
 | 
			
		||||
		struct wl_signal set_override_redirect;
 | 
			
		||||
		struct wl_signal set_geometry;
 | 
			
		||||
		struct wl_signal ping_timeout;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@ enum atom_name {
 | 
			
		|||
	NET_WM_PID,
 | 
			
		||||
	NET_WM_NAME,
 | 
			
		||||
	NET_WM_STATE,
 | 
			
		||||
	NET_WM_STRUT_PARTIAL,
 | 
			
		||||
	NET_WM_WINDOW_TYPE,
 | 
			
		||||
	WM_TAKE_FOCUS,
 | 
			
		||||
	WINDOW,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ xwayland_libs = []
 | 
			
		|||
xwayland_required = [
 | 
			
		||||
	'xcb',
 | 
			
		||||
	'xcb-composite',
 | 
			
		||||
	'xcb-ewmh',
 | 
			
		||||
	'xcb-icccm',
 | 
			
		||||
	'xcb-render',
 | 
			
		||||
	'xcb-res',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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],
 | 
			
		||||
	};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue