From d5208fa18f7e19fe2610c72712d828e1c49169ed Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 21 May 2026 13:51:52 +0200 Subject: [PATCH 01/12] xwayland/selection: stop using VLAs for MIME type atom lists The size of the VLA is client-controlled and can overflow the stack. Instead, allocate on the heap. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/work_items/4090 (cherry picked from commit cb0fa9b0a3883689179532c20a67cc8ea3b53969) --- xwayland/selection/dnd.c | 9 ++++++++- xwayland/selection/outgoing.c | 8 +++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/xwayland/selection/dnd.c b/xwayland/selection/dnd.c index 31e588baf..f80a55d4d 100644 --- a/xwayland/selection/dnd.c +++ b/xwayland/selection/dnd.c @@ -83,7 +83,12 @@ static void xwm_dnd_send_enter(struct wlr_xwm *xwm) { // data and must be retrieved with the DND_TYPE_LIST property data.data32[1] |= 1; - xcb_atom_t targets[n]; + xcb_atom_t *targets = malloc(n * sizeof(targets[0])); + if (targets == NULL) { + wlr_log(WLR_ERROR, "Allocation failed"); + return; + } + size_t i = 0; char **mime_type_ptr; wl_array_for_each(mime_type_ptr, mime_types) { @@ -99,6 +104,8 @@ static void xwm_dnd_send_enter(struct wlr_xwm *xwm) { XCB_ATOM_ATOM, 32, // format n, targets); + + free(targets); } xwm_dnd_send_event(xwm, xwm->atoms[DND_ENTER], &data); diff --git a/xwayland/selection/outgoing.c b/xwayland/selection/outgoing.c index 6216abbb4..a58c92e3e 100644 --- a/xwayland/selection/outgoing.c +++ b/xwayland/selection/outgoing.c @@ -336,7 +336,11 @@ static void xwm_selection_send_targets(struct wlr_xwm_selection *selection, } size_t n = 2 + mime_types->size / sizeof(char *); - xcb_atom_t targets[n]; + xcb_atom_t *targets = malloc(n * sizeof(targets[0])); + if (targets == NULL) { + wlr_log(WLR_ERROR, "Allocation failure"); + return; + } targets[0] = xwm->atoms[TIMESTAMP]; targets[1] = xwm->atoms[TARGETS]; @@ -356,6 +360,8 @@ static void xwm_selection_send_targets(struct wlr_xwm_selection *selection, 32, // format n, targets); + free(targets); + xwm_selection_send_notify(selection->xwm, req, true); } From 8ca360b0a3bb903ffb0dbe004fe0268126967171 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 21 May 2026 14:08:23 +0200 Subject: [PATCH 02/12] xwayland: use const pointers for xcb_get_property_value() These values must not be mutated, they are owned by the xcb_get_property_reply_t. (cherry picked from commit 9d6c9e8783f1eef575aee450a146d4fdc8ad2978) --- xwayland/selection/incoming.c | 4 ++-- xwayland/xwm.c | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/xwayland/selection/incoming.c b/xwayland/selection/incoming.c index 85d7775cd..1ae228294 100644 --- a/xwayland/selection/incoming.c +++ b/xwayland/selection/incoming.c @@ -103,7 +103,7 @@ static int write_selection_property_to_wl_client(int fd, uint32_t mask, void *data) { struct wlr_xwm_selection_transfer *transfer = data; - char *property = xcb_get_property_value(transfer->property_reply); + const char *property = xcb_get_property_value(transfer->property_reply); int remainder = xcb_get_property_value_length(transfer->property_reply) - transfer->property_start; @@ -343,7 +343,7 @@ static bool source_get_targets(struct wlr_xwm_selection *selection, return false; } - xcb_atom_t *value = xcb_get_property_value(reply); + const xcb_atom_t *value = xcb_get_property_value(reply); for (uint32_t i = 0; i < reply->value_len; i++) { char *mime_type = NULL; diff --git a/xwayland/xwm.c b/xwayland/xwm.c index e44a11743..a2cc5ef99 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -659,7 +659,7 @@ static void read_surface_class(struct wlr_xwm *xwm, } size_t len = xcb_get_property_value_length(reply); - char *class = xcb_get_property_value(reply); + const char *class = xcb_get_property_value(reply); // Unpack two sequentially stored strings: instance, class size_t instance_len = strnlen(class, len); @@ -690,7 +690,7 @@ static void read_surface_startup_id(struct wlr_xwm *xwm, } size_t len = xcb_get_property_value_length(reply); - char *startup_id = xcb_get_property_value(reply); + const char *startup_id = xcb_get_property_value(reply); free(xsurface->startup_id); if (len > 0) { @@ -719,7 +719,7 @@ static void read_surface_opacity(struct wlr_xwm *xwm, return; } - uint32_t *val = xcb_get_property_value(reply); + const uint32_t *val = xcb_get_property_value(reply); xsurface->opacity = (double)*val / UINT32_MAX; wl_signal_emit_mutable(&xsurface->events.set_opacity, NULL); } @@ -734,7 +734,7 @@ static void read_surface_role(struct wlr_xwm *xwm, } size_t len = xcb_get_property_value_length(reply); - char *role = xcb_get_property_value(reply); + const char *role = xcb_get_property_value(reply); free(xsurface->role); if (len > 0) { @@ -806,7 +806,7 @@ static void read_surface_parent(struct wlr_xwm *xwm, } struct wlr_xwayland_surface *found_parent = NULL; - xcb_window_t *xid = xcb_get_property_value(reply); + const xcb_window_t *xid = xcb_get_property_value(reply); if (reply->type != XCB_ATOM_NONE && xid != NULL) { found_parent = lookup_surface(xwm, *xid); if (!has_parent(found_parent, xsurface)) { @@ -837,7 +837,7 @@ static void read_surface_window_type(struct wlr_xwm *xwm, return; } - xcb_atom_t *atoms = xcb_get_property_value(reply); + const xcb_atom_t *atoms = xcb_get_property_value(reply); size_t atoms_len = reply->value_len; size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; @@ -864,7 +864,7 @@ static void read_surface_protocols(struct wlr_xwm *xwm, return; } - xcb_atom_t *atoms = xcb_get_property_value(reply); + const xcb_atom_t *atoms = xcb_get_property_value(reply); size_t atoms_len = reply->value_len; size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; @@ -981,7 +981,7 @@ static void read_surface_motif_hints(struct wlr_xwm *xwm, return; } - uint32_t *motif_hints = xcb_get_property_value(reply); + const uint32_t *motif_hints = xcb_get_property_value(reply); if (motif_hints[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) { xsurface->decorations = WLR_XWAYLAND_SURFACE_DECORATIONS_ALL; uint32_t decorations = motif_hints[MWM_HINTS_DECORATIONS_FIELD]; @@ -1029,7 +1029,7 @@ static void read_surface_net_wm_state(struct wlr_xwm *xwm, struct wlr_xwayland_surface *xsurface, xcb_get_property_reply_t *reply) { xsurface->fullscreen = 0; - xcb_atom_t *atom = xcb_get_property_value(reply); + const xcb_atom_t *atom = xcb_get_property_value(reply); for (uint32_t i = 0; i < reply->value_len; i++) { if (atom[i] == xwm->atoms[NET_WM_STATE_MODAL]) { xsurface->modal = true; From 4412992469540b1d578cb94a5cd4e6e5829812dc Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 21 May 2026 14:10:50 +0200 Subject: [PATCH 03/12] xwayland/xwm: fix out-of-bounds strndup() in read_surface_class() We advance the class pointer here, but we forgot to decrease the length. (cherry picked from commit 851cdd0089004884bd85a95ad21f04009cb5a53a) --- xwayland/xwm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index a2cc5ef99..c73f5a7f4 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -667,6 +667,7 @@ static void read_surface_class(struct wlr_xwm *xwm, if (len > 0 && instance_len < len) { surface->instance = strndup(class, instance_len); class += instance_len + 1; + len -= instance_len + 1; } else { surface->instance = NULL; } From 9d4fc33b87e1f3f903be1b61452abacd095ec543 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 21 May 2026 14:31:18 +0200 Subject: [PATCH 04/12] xwayland/xwm: pluralize array variable in read_surface_net_wm_state() Make it clear this doesn't contain a single atom. (cherry picked from commit 5cb537395966bd96768b5ddc870894940932ae5e) --- xwayland/xwm.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index c73f5a7f4..2a9a308d2 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1030,31 +1030,31 @@ static void read_surface_net_wm_state(struct wlr_xwm *xwm, struct wlr_xwayland_surface *xsurface, xcb_get_property_reply_t *reply) { xsurface->fullscreen = 0; - const xcb_atom_t *atom = xcb_get_property_value(reply); + const xcb_atom_t *atoms = xcb_get_property_value(reply); for (uint32_t i = 0; i < reply->value_len; i++) { - if (atom[i] == xwm->atoms[NET_WM_STATE_MODAL]) { + if (atoms[i] == xwm->atoms[NET_WM_STATE_MODAL]) { xsurface->modal = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_FULLSCREEN]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_FULLSCREEN]) { xsurface->fullscreen = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_MAXIMIZED_VERT]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_MAXIMIZED_VERT]) { xsurface->maximized_vert = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) { xsurface->maximized_horz = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_HIDDEN]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_HIDDEN]) { xsurface->minimized = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_STICKY]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_STICKY]) { xsurface->sticky = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_SHADED]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_SHADED]) { xsurface->shaded = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_SKIP_TASKBAR]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_SKIP_TASKBAR]) { xsurface->skip_taskbar = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_SKIP_PAGER]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_SKIP_PAGER]) { xsurface->skip_pager = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_ABOVE]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_ABOVE]) { xsurface->above = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_BELOW]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_BELOW]) { xsurface->below = true; - } else if (atom[i] == xwm->atoms[NET_WM_STATE_DEMANDS_ATTENTION]) { + } else if (atoms[i] == xwm->atoms[NET_WM_STATE_DEMANDS_ATTENTION]) { xsurface->demands_attention = true; } } From 1aac9974d52178dcb7dd383769c14003325977d1 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 21 May 2026 14:32:51 +0200 Subject: [PATCH 05/12] xwayland: stop using xcb_get_property_reply_t.value_len This field is difficult to use correctly, its meaning depends on format. xcb docs read: > You should use the corresponding accessor instead of this field. Replace all uses with the safe accessor. This fixes potential out-of-bounds array accesses when the format field isn't what we expect. (cherry picked from commit c91543352aff18052946e6ac3703a152f66307d7) --- xwayland/selection/incoming.c | 3 ++- xwayland/xwm.c | 22 ++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/xwayland/selection/incoming.c b/xwayland/selection/incoming.c index 1ae228294..b4f744ee2 100644 --- a/xwayland/selection/incoming.c +++ b/xwayland/selection/incoming.c @@ -344,7 +344,8 @@ static bool source_get_targets(struct wlr_xwm_selection *selection, } const xcb_atom_t *value = xcb_get_property_value(reply); - for (uint32_t i = 0; i < reply->value_len; i++) { + uint32_t value_len = xcb_get_property_value_length(reply) / sizeof(value); + for (uint32_t i = 0; i < value_len; i++) { char *mime_type = NULL; if (value[i] == xwm->atoms[UTF8_STRING]) { diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 2a9a308d2..7206403fe 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -839,8 +839,8 @@ static void read_surface_window_type(struct wlr_xwm *xwm, } const xcb_atom_t *atoms = xcb_get_property_value(reply); - size_t atoms_len = reply->value_len; - size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; + size_t atoms_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]); + size_t atoms_size = sizeof(atoms[0]) * atoms_len; free(xsurface->window_type); if (atoms_len > 0) { @@ -866,8 +866,8 @@ static void read_surface_protocols(struct wlr_xwm *xwm, } const xcb_atom_t *atoms = xcb_get_property_value(reply); - size_t atoms_len = reply->value_len; - size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; + size_t atoms_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]); + size_t atoms_size = sizeof(atoms[0]) * atoms_len; free(xsurface->protocols); if (atoms_len > 0) { @@ -894,7 +894,7 @@ static void read_surface_hints(struct wlr_xwm *xwm, } free(xsurface->hints); - if (reply->value_len > 0) { + if (xcb_get_property_value_length(reply) > 0) { xsurface->hints = calloc(1, sizeof(*xsurface->hints)); if (xsurface->hints == NULL) { return; @@ -924,7 +924,7 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm, free(xsurface->size_hints); xsurface->size_hints = NULL; - if (reply->value_len == 0) { + if (xcb_get_property_value_length(reply) == 0) { return; } @@ -971,18 +971,19 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm, static void read_surface_motif_hints(struct wlr_xwm *xwm, struct wlr_xwayland_surface *xsurface, xcb_get_property_reply_t *reply) { - if (reply->value_len == 0) { + if (xcb_get_property_value_length(reply) == 0) { xsurface->decorations = 0; wl_signal_emit_mutable(&xsurface->events.set_decorations, NULL); return; } - if (reply->value_len < 5) { + const uint32_t *motif_hints = xcb_get_property_value(reply); + int motif_hints_len = xcb_get_property_value_length(reply) / sizeof(motif_hints[0]); + if (motif_hints_len < 5) { wlr_log(WLR_DEBUG, "Invalid MOTIF_WM_HINTS property type"); return; } - const uint32_t *motif_hints = xcb_get_property_value(reply); if (motif_hints[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) { xsurface->decorations = WLR_XWAYLAND_SURFACE_DECORATIONS_ALL; uint32_t decorations = motif_hints[MWM_HINTS_DECORATIONS_FIELD]; @@ -1031,7 +1032,8 @@ static void read_surface_net_wm_state(struct wlr_xwm *xwm, xcb_get_property_reply_t *reply) { xsurface->fullscreen = 0; const xcb_atom_t *atoms = xcb_get_property_value(reply); - for (uint32_t i = 0; i < reply->value_len; i++) { + uint32_t atoms_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]); + for (uint32_t i = 0; i < atoms_len; i++) { if (atoms[i] == xwm->atoms[NET_WM_STATE_MODAL]) { xsurface->modal = true; } else if (atoms[i] == xwm->atoms[NET_WM_STATE_FULLSCREEN]) { From f0a04a1f8a261b62505dd860adee5fe1c0e88c43 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 22 May 2026 19:48:09 +0200 Subject: [PATCH 06/12] xwayland/xwm: align WL_SURFACE_ID error message with WL_SURFACE_SERIAL (cherry picked from commit 73d6968cd00c7549677fcc3c4a4ae4f9b012c41f) --- xwayland/xwm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 7206403fe..fd4356eee 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1462,7 +1462,7 @@ static void xwm_handle_surface_id_message(struct wlr_xwm *xwm, struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->window); if (xsurface == NULL) { wlr_log(WLR_DEBUG, - "client message WL_SURFACE_ID but no new window %u ?", + "Received client message WL_SURFACE_ID but no X11 window %u", ev->window); return; } From 90920192d329efa4f0e14b5782754e18cefb943e Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 22 May 2026 19:51:11 +0200 Subject: [PATCH 07/12] xwayland/xwm: expand comment about WL_SURFACE_ID event ordering Make it clearer what's up. (cherry picked from commit 041aa8c0488a4bcfab220aaa841e926a5639d788) --- xwayland/xwm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index fd4356eee..7eb9e93c1 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1466,8 +1466,12 @@ static void xwm_handle_surface_id_message(struct wlr_xwm *xwm, ev->window); return; } - /* Check if we got notified after wayland surface create event */ + uint32_t id = ev->data.data32[0]; + + // Because the X11 and Wayland connections are separate sockets, the + // WL_SURFACE_ID and wl_compositor.create_surface messages may be received + // in any order. struct wl_resource *resource = wl_client_get_object(xwm->xwayland->server->client, id); if (resource) { From 94e62783a1ce727d271dcaa8c921a1ee7d772051 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 22 May 2026 20:05:17 +0200 Subject: [PATCH 08/12] xwayland/xwm: check whether surface is already associated for WL_SURFACE_ID xwayland_surface_associate() asserts that the surface has not yet been associated yet. Arbitrary clients can send these messages, don't abort when that happens. (cherry picked from commit 8154d80a4d39e03c1ccc80b9a2e8a04b40a2091e) --- xwayland/xwm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 7eb9e93c1..8e3233f81 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1466,6 +1466,11 @@ static void xwm_handle_surface_id_message(struct wlr_xwm *xwm, ev->window); return; } + if (xsurface->surface != NULL) { + wlr_log(WLR_DEBUG, "Received multiple client messages WL_SURFACE_ID " + "for an already-associated X11 window %u", ev->window); + return; + } uint32_t id = ev->data.data32[0]; From 2bacd749ec4dc95381fa2fd97873f5b0fe3d1e21 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 22 May 2026 20:10:12 +0200 Subject: [PATCH 09/12] xwayland/xwm: check object type in xwm_handle_surface_id_message() wlr_surface_from_resource() asserts that the object is a wl_surface. Since arbitrary clients can send such messages, avoid aborting on invalid input. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/work_items/4093 (cherry picked from commit c6e2af1155257f92857bbd05ac4d721a86c4cc5a) --- xwayland/xwm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 8e3233f81..041444065 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1480,6 +1480,13 @@ static void xwm_handle_surface_id_message(struct wlr_xwm *xwm, struct wl_resource *resource = wl_client_get_object(xwm->xwayland->server->client, id); if (resource) { + if (wl_resource_get_interface(resource) != &wl_surface_interface) { + wlr_log(WLR_DEBUG, "Received client message WL_SURFACE_ID " + "for X11 window %u but Wayland object is not a wl_surface", + ev->window); + return; + } + struct wlr_surface *surface = wlr_surface_from_resource(resource); xwayland_surface_associate(xwm, xsurface, surface); } else { From 5af4343bba4cf3616dd5b2ffeb992104e5cf41aa Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 11 Jun 2026 16:49:00 +0200 Subject: [PATCH 10/12] xwayland/xwm: check WM_TRANSIENT_FOR length Without this check, the reply value might be smaller than xcb_window_t and will result in an invalid memory read. Reported-by: Tristan (cherry picked from commit 63318d28b1ea86873eeb1023d88e56d57bdd2453) --- xwayland/xwm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 041444065..1706d7080 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -807,8 +807,12 @@ static void read_surface_parent(struct wlr_xwm *xwm, } struct wlr_xwayland_surface *found_parent = NULL; - const xcb_window_t *xid = xcb_get_property_value(reply); - if (reply->type != XCB_ATOM_NONE && xid != NULL) { + if (reply->type != XCB_ATOM_NONE) { + if (xcb_get_property_value_length(reply) != sizeof(xcb_window_t)) { + wlr_log(WLR_DEBUG, "Invalid WM_TRANSIENT_FOR property length"); + return; + } + const xcb_window_t *xid = xcb_get_property_value(reply); found_parent = lookup_surface(xwm, *xid); if (!has_parent(found_parent, xsurface)) { xsurface->parent = found_parent; From 9843c7ffaa7be9b7f7fde35ae8d42471caa26eac Mon Sep 17 00:00:00 2001 From: rewine Date: Tue, 2 Jun 2026 17:02:21 +0800 Subject: [PATCH 11/12] xwayland: emit set_parent signal when parent is destroyed When a xwayland surface is destroyed, its children's parent pointer is set to NULL, but the set_parent signal was not emitted. (cherry picked from commit a94cd29eb13fc2fb68f2fe2d053fef29fb6ae712) --- xwayland/xwm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 1706d7080..f31163d94 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -630,6 +630,7 @@ static void xwayland_surface_destroy(struct wlr_xwayland_surface *xsurface) { wl_list_remove(&child->parent_link); wl_list_init(&child->parent_link); child->parent = NULL; + wl_signal_emit_mutable(&child->events.set_parent, NULL); } wl_list_remove(&xsurface->unpaired_link); From c484b94767a24f1d244e9abe106e9d629ee4f35b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Poisot?= Date: Fri, 22 May 2026 20:13:24 +0000 Subject: [PATCH 12/12] scene: don't send new dmabuf feedback after node disable The comparison done in `scene_buffer_send_dmabuf_feedback()` is sufficient. Close https://gitlab.freedesktop.org/wlroots/wlroots/-/work_items/4088 (cherry picked from commit 3bd8f29b138e2832870ad05a9386002fcc79e0fc) --- types/scene/wlr_scene.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index 54c09bbfe..e06fd31f8 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -476,11 +476,6 @@ static void update_node_update_outputs(struct wlr_scene_node *node, } } - if (old_primary_output != scene_buffer->primary_output) { - scene_buffer->prev_feedback_options = - (struct wlr_linux_dmabuf_feedback_v1_init_options){0}; - } - uint64_t old_active = scene_buffer->active_outputs; scene_buffer->active_outputs = active_outputs;