132 lines
4.9 KiB
Diff
132 lines
4.9 KiB
Diff
From 1e7dd78cfda8ddd7c618c01973799aedcddfb72f Mon Sep 17 00:00:00 2001
|
|
Message-ID: <1e7dd78cfda8ddd7c618c01973799aedcddfb72f.1741276434.git.agx@sigxcpu.org>
|
|
From: =?UTF-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org>
|
|
Date: Tue, 4 Mar 2025 20:37:49 +0100
|
|
Subject: [PATCH] xwm: Handle NET_WM_WINDOW_OPACITY
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Lot of clients use it (e.g. both Qt and GTK) although it never made it
|
|
into the spec at
|
|
|
|
https://specifications.freedesktop.org/wm-spec/latest-single/
|
|
|
|
until recently
|
|
|
|
https://gitlab.freedesktop.org/xdg/xdg-specs/-/merge_requests/97
|
|
|
|
(cherry picked from commit e752e3ec06fc7c2b83079a5980218ae359b1c869)
|
|
|
|
Signed-off-by: Guido Günther <agx@sigxcpu.org>
|
|
---
|
|
include/wlr/xwayland/xwayland.h | 2 ++
|
|
include/xwayland/xwm.h | 1 +
|
|
xwayland/xwm.c | 23 +++++++++++++++++++++++
|
|
3 files changed, 26 insertions(+)
|
|
|
|
diff --git a/include/wlr/xwayland/xwayland.h b/include/wlr/xwayland/xwayland.h
|
|
index 4b476a03..d0bbe993 100644
|
|
--- a/include/wlr/xwayland/xwayland.h
|
|
+++ b/include/wlr/xwayland/xwayland.h
|
|
@@ -119,6 +119,7 @@ struct wlr_xwayland_surface {
|
|
int16_t x, y;
|
|
uint16_t width, height;
|
|
bool override_redirect;
|
|
+ float opacity;
|
|
|
|
char *title;
|
|
char *class;
|
|
@@ -186,6 +187,7 @@ struct wlr_xwayland_surface {
|
|
struct wl_signal set_strut_partial;
|
|
struct wl_signal set_override_redirect;
|
|
struct wl_signal set_geometry;
|
|
+ struct wl_signal set_opacity;
|
|
/* can be used to set initial maximized/fullscreen geometry */
|
|
struct wl_signal map_request;
|
|
struct wl_signal ping_timeout;
|
|
diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h
|
|
index 4386446d..43e36328 100644
|
|
--- a/include/xwayland/xwm.h
|
|
+++ b/include/xwayland/xwm.h
|
|
@@ -62,6 +62,7 @@ enum atom_name {
|
|
NET_STARTUP_ID,
|
|
NET_STARTUP_INFO,
|
|
NET_STARTUP_INFO_BEGIN,
|
|
+ NET_WM_WINDOW_OPACITY,
|
|
NET_WM_WINDOW_TYPE_NORMAL,
|
|
NET_WM_WINDOW_TYPE_UTILITY,
|
|
NET_WM_WINDOW_TYPE_TOOLTIP,
|
|
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
|
|
index b315fa0f..91ca596a 100644
|
|
--- a/xwayland/xwm.c
|
|
+++ b/xwayland/xwm.c
|
|
@@ -61,6 +61,7 @@ static const char *const atom_map[ATOM_LAST] = {
|
|
[NET_STARTUP_ID] = "_NET_STARTUP_ID",
|
|
[NET_STARTUP_INFO] = "_NET_STARTUP_INFO",
|
|
[NET_STARTUP_INFO_BEGIN] = "_NET_STARTUP_INFO_BEGIN",
|
|
+ [NET_WM_WINDOW_OPACITY] = "_NET_WM_WINDOW_OPACITY",
|
|
[NET_WM_WINDOW_TYPE_NORMAL] = "_NET_WM_WINDOW_TYPE_NORMAL",
|
|
[NET_WM_WINDOW_TYPE_UTILITY] = "_NET_WM_WINDOW_TYPE_UTILITY",
|
|
[NET_WM_WINDOW_TYPE_TOOLTIP] = "_NET_WM_WINDOW_TYPE_TOOLTIP",
|
|
@@ -194,6 +195,7 @@ static struct wlr_xwayland_surface *xwayland_surface_create(
|
|
surface->width = width;
|
|
surface->height = height;
|
|
surface->override_redirect = override_redirect;
|
|
+ surface->opacity = 1.0;
|
|
wl_list_init(&surface->children);
|
|
wl_list_init(&surface->stack_link);
|
|
wl_list_init(&surface->parent_link);
|
|
@@ -219,6 +221,7 @@ static struct wlr_xwayland_surface *xwayland_surface_create(
|
|
wl_signal_init(&surface->events.set_strut_partial);
|
|
wl_signal_init(&surface->events.set_override_redirect);
|
|
wl_signal_init(&surface->events.set_geometry);
|
|
+ wl_signal_init(&surface->events.set_opacity);
|
|
wl_signal_init(&surface->events.map_request);
|
|
wl_signal_init(&surface->events.ping_timeout);
|
|
|
|
@@ -485,6 +488,8 @@ static void xwayland_surface_destroy(struct wlr_xwayland_surface *xsurface) {
|
|
|
|
wl_signal_emit_mutable(&xsurface->events.destroy, NULL);
|
|
|
|
+ assert(wl_list_empty(&xsurface->events.set_opacity.listener_list));
|
|
+
|
|
if (xsurface == xsurface->xwm->focus_surface) {
|
|
xwm_surface_activate(xsurface->xwm, NULL);
|
|
}
|
|
@@ -568,6 +573,22 @@ static void read_surface_startup_id(struct wlr_xwm *xwm,
|
|
wl_signal_emit_mutable(&xsurface->events.set_startup_id, NULL);
|
|
}
|
|
|
|
+static void read_surface_opacity(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(uint32_t)) {
|
|
+ uint32_t *val = xcb_get_property_value(reply);
|
|
+
|
|
+ xsurface->opacity = (double)*val / UINT32_MAX;
|
|
+ wl_signal_emit_mutable(&xsurface->events.set_opacity, NULL);
|
|
+ } else if (reply->type == XCB_ATOM_NONE) {
|
|
+ xsurface->opacity = 1.0;
|
|
+ wl_signal_emit_mutable(&xsurface->events.set_opacity, NULL);
|
|
+ }
|
|
+}
|
|
+
|
|
static void read_surface_role(struct wlr_xwm *xwm,
|
|
struct wlr_xwayland_surface *xsurface,
|
|
xcb_get_property_reply_t *reply) {
|
|
@@ -882,6 +903,8 @@ static void read_surface_property(struct wlr_xwm *xwm,
|
|
read_surface_role(xwm, xsurface, reply);
|
|
} else if (property == xwm->atoms[NET_STARTUP_ID]) {
|
|
read_surface_startup_id(xwm, xsurface, reply);
|
|
+ } else if (property == xwm->atoms[NET_WM_WINDOW_OPACITY]) {
|
|
+ read_surface_opacity(xwm, xsurface, reply);
|
|
} else if (wlr_log_get_verbosity() >= WLR_DEBUG) {
|
|
char *prop_name = xwm_get_atom_name(xwm, property);
|
|
wlr_log(WLR_DEBUG, "unhandled X11 property %" PRIu32 " (%s) for window %" PRIu32,
|
|
--
|
|
2.47.2
|
|
|