mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2024-11-29 02:22:20 +00: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
@ -12,6 +12,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xcb_ewmh.h>
|
||||||
#include <xcb/xcb_icccm.h>
|
#include <xcb/xcb_icccm.h>
|
||||||
#include <wlr/util/addon.h>
|
#include <wlr/util/addon.h>
|
||||||
|
|
||||||
@ -121,6 +122,11 @@ struct wlr_xwayland_surface {
|
|||||||
uint32_t decorations;
|
uint32_t decorations;
|
||||||
xcb_icccm_wm_hints_t *hints;
|
xcb_icccm_wm_hints_t *hints;
|
||||||
xcb_size_hints_t *size_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;
|
bool pinging;
|
||||||
struct wl_event_source *ping_timer;
|
struct wl_event_source *ping_timer;
|
||||||
@ -154,6 +160,7 @@ struct wlr_xwayland_surface {
|
|||||||
struct wl_signal set_window_type;
|
struct wl_signal set_window_type;
|
||||||
struct wl_signal set_hints;
|
struct wl_signal set_hints;
|
||||||
struct wl_signal set_decorations;
|
struct wl_signal set_decorations;
|
||||||
|
struct wl_signal set_strut_partial;
|
||||||
struct wl_signal set_override_redirect;
|
struct wl_signal set_override_redirect;
|
||||||
struct wl_signal set_geometry;
|
struct wl_signal set_geometry;
|
||||||
struct wl_signal ping_timeout;
|
struct wl_signal ping_timeout;
|
||||||
|
@ -34,6 +34,7 @@ enum atom_name {
|
|||||||
NET_WM_PID,
|
NET_WM_PID,
|
||||||
NET_WM_NAME,
|
NET_WM_NAME,
|
||||||
NET_WM_STATE,
|
NET_WM_STATE,
|
||||||
|
NET_WM_STRUT_PARTIAL,
|
||||||
NET_WM_WINDOW_TYPE,
|
NET_WM_WINDOW_TYPE,
|
||||||
WM_TAKE_FOCUS,
|
WM_TAKE_FOCUS,
|
||||||
WINDOW,
|
WINDOW,
|
||||||
|
@ -2,6 +2,7 @@ xwayland_libs = []
|
|||||||
xwayland_required = [
|
xwayland_required = [
|
||||||
'xcb',
|
'xcb',
|
||||||
'xcb-composite',
|
'xcb-composite',
|
||||||
|
'xcb-ewmh',
|
||||||
'xcb-icccm',
|
'xcb-icccm',
|
||||||
'xcb-render',
|
'xcb-render',
|
||||||
'xcb-res',
|
'xcb-res',
|
||||||
|
@ -36,6 +36,7 @@ const char *const atom_map[ATOM_LAST] = {
|
|||||||
[NET_WM_PID] = "_NET_WM_PID",
|
[NET_WM_PID] = "_NET_WM_PID",
|
||||||
[NET_WM_NAME] = "_NET_WM_NAME",
|
[NET_WM_NAME] = "_NET_WM_NAME",
|
||||||
[NET_WM_STATE] = "_NET_WM_STATE",
|
[NET_WM_STATE] = "_NET_WM_STATE",
|
||||||
|
[NET_WM_STRUT_PARTIAL] = "_NET_WM_STRUT_PARTIAL",
|
||||||
[NET_WM_WINDOW_TYPE] = "_NET_WM_WINDOW_TYPE",
|
[NET_WM_WINDOW_TYPE] = "_NET_WM_WINDOW_TYPE",
|
||||||
[WM_TAKE_FOCUS] = "WM_TAKE_FOCUS",
|
[WM_TAKE_FOCUS] = "WM_TAKE_FOCUS",
|
||||||
[WINDOW] = "WINDOW",
|
[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_window_type);
|
||||||
wl_signal_init(&surface->events.set_hints);
|
wl_signal_init(&surface->events.set_hints);
|
||||||
wl_signal_init(&surface->events.set_decorations);
|
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.set_override_redirect);
|
||||||
wl_signal_init(&surface->events.ping_timeout);
|
wl_signal_init(&surface->events.ping_timeout);
|
||||||
wl_signal_init(&surface->events.set_geometry);
|
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->startup_id);
|
||||||
free(xsurface->hints);
|
free(xsurface->hints);
|
||||||
free(xsurface->size_hints);
|
free(xsurface->size_hints);
|
||||||
|
free(xsurface->strut_partial);
|
||||||
free(xsurface);
|
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,
|
static void read_surface_net_wm_state(struct wlr_xwm *xwm,
|
||||||
struct wlr_xwayland_surface *xsurface,
|
struct wlr_xwayland_surface *xsurface,
|
||||||
xcb_get_property_reply_t *reply) {
|
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);
|
read_surface_normal_hints(xwm, xsurface, reply);
|
||||||
} else if (property == xwm->atoms[MOTIF_WM_HINTS]) {
|
} else if (property == xwm->atoms[MOTIF_WM_HINTS]) {
|
||||||
read_surface_motif_hints(xwm, xsurface, reply);
|
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]) {
|
} else if (property == xwm->atoms[WM_WINDOW_ROLE]) {
|
||||||
read_surface_role(xwm, xsurface, reply);
|
read_surface_role(xwm, xsurface, reply);
|
||||||
} else if (property == xwm->atoms[NET_STARTUP_ID]) {
|
} 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[MOTIF_WM_HINTS],
|
||||||
xwm->atoms[NET_STARTUP_ID],
|
xwm->atoms[NET_STARTUP_ID],
|
||||||
xwm->atoms[NET_WM_STATE],
|
xwm->atoms[NET_WM_STATE],
|
||||||
|
xwm->atoms[NET_WM_STRUT_PARTIAL],
|
||||||
xwm->atoms[NET_WM_WINDOW_TYPE],
|
xwm->atoms[NET_WM_WINDOW_TYPE],
|
||||||
xwm->atoms[NET_WM_NAME],
|
xwm->atoms[NET_WM_NAME],
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user