Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package wlroots for openSUSE:Factory checked in at 2026-07-08 17:38:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/wlroots (Old) and /work/SRC/openSUSE:Factory/.wlroots.new.1982 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "wlroots" Wed Jul 8 17:38:27 2026 rev:43 rq:1364463 version:0.20.2 Changes: -------- --- /work/SRC/openSUSE:Factory/wlroots/wlroots.changes 2026-05-27 16:19:05.842167248 +0200 +++ /work/SRC/openSUSE:Factory/.wlroots.new.1982/wlroots.changes 2026-07-08 17:41:39.796188054 +0200 @@ -1,0 +2,26 @@ +Tue Jul 7 22:49:27 UTC 2026 - zeus <[email protected]> + +- Update to 0.20.2: + * xwayland/selection: stop using VLAs for MIME type atom lists + * xwayland: use const pointers for xcb_get_property_value() + * xwayland/xwm: fix out-of-bounds strndup() in + read_surface_class() + * xwayland/xwm: pluralize array variable in + read_surface_net_wm_state() + * xwayland: stop using xcb_get_property_reply_t.value_len + * xwayland/xwm: align WL_SURFACE_ID error message with + WL_SURFACE_SERIAL + * xwayland/xwm: expand comment about WL_SURFACE_ID event ordering + * xwayland/xwm: check whether surface is already associated for + WL_SURFACE_ID + * xwayland/xwm: check object type in + xwm_handle_surface_id_message() + * xwayland/xwm: check WM_TRANSIENT_FOR length + * scene: intersect visible area with output layout in + update_node_update_outputs() + * security_context_v1: set CLOEXEC for client FDs + * xwayland:use size of the pointed type instead of pointer + * xwayland: emit set_parent signal when parent is destroyed + * drag: check dnd action and accepted on touch up + +------------------------------------------------------------------- Old: ---- wlroots-0.20.1.tar.gz wlroots-0.20.1.tar.gz.sig New: ---- wlroots-0.20.2.tar.gz wlroots-0.20.2.tar.gz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ wlroots.spec ++++++ --- /var/tmp/diff_new_pack.gZ4iBB/_old 2026-07-08 17:41:41.296240327 +0200 +++ /var/tmp/diff_new_pack.gZ4iBB/_new 2026-07-08 17:41:41.308240745 +0200 @@ -18,7 +18,7 @@ %global ver_suffix 0.20 %global sover 0_20 -%global patch_ver 1 +%global patch_ver 2 %global libname libwlroots-%{sover} %bcond_without drm_backend %bcond_without libinput_backend ++++++ wlroots-0.20.1.tar.gz -> wlroots-0.20.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/include/util/fd.h new/wlroots-0.20.2/include/util/fd.h --- old/wlroots-0.20.1/include/util/fd.h 1970-01-01 01:00:00.000000000 +0100 +++ new/wlroots-0.20.2/include/util/fd.h 2026-07-07 23:46:09.000000000 +0200 @@ -0,0 +1,8 @@ +#ifndef UTIL_FD_H +#define UTIL_FD_H + +#include <stdbool.h> + +bool set_cloexec(int fd, bool cloexec); + +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/meson.build new/wlroots-0.20.2/meson.build --- old/wlroots-0.20.1/meson.build 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/meson.build 2026-07-07 23:46:09.000000000 +0200 @@ -1,7 +1,7 @@ project( 'wlroots', 'c', - version: '0.20.1', + version: '0.20.2', license: 'MIT', meson_version: '>=1.3', default_options: [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/types/data_device/wlr_drag.c new/wlroots-0.20.2/types/data_device/wlr_drag.c --- old/wlroots-0.20.1/types/data_device/wlr_drag.c 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/types/data_device/wlr_drag.c 2026-07-07 23:46:09.000000000 +0200 @@ -290,7 +290,8 @@ return 0; } - if (drag->focus_client) { + if (drag->focus_client && drag->source->current_dnd_action && + drag->source->accepted) { drag_drop(drag, time); } else if (drag->source->impl->dnd_finish) { // This will end the grab and free `drag` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/types/scene/wlr_scene.c new/wlroots-0.20.2/types/scene/wlr_scene.c --- old/wlroots-0.20.1/types/scene/wlr_scene.c 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/types/scene/wlr_scene.c 2026-07-07 23:46:09.000000000 +0200 @@ -430,7 +430,21 @@ uint64_t active_outputs = 0; if (!pixman_region32_empty(&node->visible)) { - uint32_t visible_area = region_area(&node->visible); + struct wlr_scene_output *scene_output; + + // Compute the region covered by all outputs, then intersect with the + // node's visible region + pixman_region32_t visible; + pixman_region32_init(&visible); + wl_list_for_each(scene_output, outputs, link) { + int width, height; + wlr_output_effective_resolution(scene_output->output, &width, &height); + pixman_region32_union_rect(&visible, &visible, + scene_output->x, scene_output->y, width, height); + } + pixman_region32_intersect(&visible, &visible, &node->visible); + uint32_t visible_area = region_area(&visible); + pixman_region32_fini(&visible); // let's update the outputs in two steps: // - the primary outputs @@ -438,7 +452,6 @@ // This ensures that the enter/leave signals can rely on the primary output // to have a reasonable value. Otherwise, they may get a value that's in // the middle of a calculation. - struct wlr_scene_output *scene_output; wl_list_for_each(scene_output, outputs, link) { if (scene_output == ignore) { continue; @@ -462,9 +475,9 @@ uint32_t overlap = region_area(&intersection); pixman_region32_fini(&intersection); - // If the overlap accounts for less than 10% of the visible node area, + // If the overlap accounts for 10% of the visible node area or less, // ignore this output - if (overlap >= 0.1 * visible_area) { + if (overlap > 0.1 * visible_area) { if (overlap >= largest_overlap) { largest_overlap = overlap; scene_buffer->primary_output = scene_output; @@ -476,11 +489,6 @@ } } - 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; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/types/wlr_security_context_v1.c new/wlroots-0.20.2/types/wlr_security_context_v1.c --- old/wlroots-0.20.1/types/wlr_security_context_v1.c 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/types/wlr_security_context_v1.c 2026-07-07 23:46:09.000000000 +0200 @@ -7,6 +7,7 @@ #include <wlr/types/wlr_security_context_v1.h> #include <wlr/util/log.h> #include "security-context-v1-protocol.h" +#include "util/fd.h" #define SECURITY_CONTEXT_MANAGER_V1_VERSION 1 @@ -129,6 +130,11 @@ return 0; } + if (!set_cloexec(client_fd, true)) { + close(client_fd); + return 0; + } + struct wlr_security_context_v1_client *security_context_client = calloc(1, sizeof(*security_context_client)); if (security_context_client == NULL) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/util/fd.c new/wlroots-0.20.2/util/fd.c --- old/wlroots-0.20.1/util/fd.c 1970-01-01 01:00:00.000000000 +0100 +++ new/wlroots-0.20.2/util/fd.c 2026-07-07 23:46:09.000000000 +0200 @@ -0,0 +1,22 @@ +#include <fcntl.h> +#include <wlr/util/log.h> + +#include "util/fd.h" + +bool set_cloexec(int fd, bool cloexec) { + int flags = fcntl(fd, F_GETFD); + if (flags == -1) { + wlr_log_errno(WLR_ERROR, "fcntl failed"); + return false; + } + if (cloexec) { + flags = flags | FD_CLOEXEC; + } else { + flags = flags & ~FD_CLOEXEC; + } + if (fcntl(fd, F_SETFD, flags) == -1) { + wlr_log_errno(WLR_ERROR, "fcntl failed"); + return false; + } + return true; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/util/meson.build new/wlroots-0.20.2/util/meson.build --- old/wlroots-0.20.1/util/meson.build 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/util/meson.build 2026-07-07 23:46:09.000000000 +0200 @@ -3,6 +3,7 @@ 'array.c', 'box.c', 'env.c', + 'fd.c', 'global.c', 'log.c', 'matrix.c', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/xwayland/selection/dnd.c new/wlroots-0.20.2/xwayland/selection/dnd.c --- old/wlroots-0.20.1/xwayland/selection/dnd.c 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/xwayland/selection/dnd.c 2026-07-07 23:46:09.000000000 +0200 @@ -83,7 +83,12 @@ // 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 @@ XCB_ATOM_ATOM, 32, // format n, targets); + + free(targets); } xwm_dnd_send_event(xwm, xwm->atoms[DND_ENTER], &data); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/xwayland/selection/incoming.c new/wlroots-0.20.2/xwayland/selection/incoming.c --- old/wlroots-0.20.1/xwayland/selection/incoming.c 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/xwayland/selection/incoming.c 2026-07-07 23:46:09.000000000 +0200 @@ -103,7 +103,7 @@ 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,8 +343,9 @@ return false; } - xcb_atom_t *value = xcb_get_property_value(reply); - for (uint32_t i = 0; i < reply->value_len; i++) { + const xcb_atom_t *value = xcb_get_property_value(reply); + uint32_t value_len = xcb_get_property_value_length(reply) / sizeof(value[0]); + for (uint32_t i = 0; i < value_len; i++) { char *mime_type = NULL; if (value[i] == xwm->atoms[UTF8_STRING]) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/xwayland/selection/outgoing.c new/wlroots-0.20.2/xwayland/selection/outgoing.c --- old/wlroots-0.20.1/xwayland/selection/outgoing.c 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/xwayland/selection/outgoing.c 2026-07-07 23:46:09.000000000 +0200 @@ -336,7 +336,11 @@ } 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 @@ 32, // format n, targets); + free(targets); + xwm_selection_send_notify(selection->xwm, req, true); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/xwayland/server.c new/wlroots-0.20.2/xwayland/server.c --- old/wlroots-0.20.1/xwayland/server.c 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/xwayland/server.c 2026-07-07 23:46:09.000000000 +0200 @@ -16,6 +16,7 @@ #include <wlr/xwayland.h> #include "config.h" #include "sockets.h" +#include "util/fd.h" static void safe_close(int fd) { if (fd >= 0) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/xwayland/sockets.c new/wlroots-0.20.2/xwayland/sockets.c --- old/wlroots-0.20.1/xwayland/sockets.c 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/xwayland/sockets.c 2026-07-07 23:46:09.000000000 +0200 @@ -14,6 +14,7 @@ #include <unistd.h> #include <wlr/util/log.h> #include "sockets.h" +#include "util/fd.h" static const char lock_fmt[] = "/tmp/.X%d-lock"; static const char socket_dir[] = "/tmp/.X11-unix"; @@ -22,24 +23,6 @@ static const char socket_fmt2[] = "/tmp/.X11-unix/X%d_"; #endif -bool set_cloexec(int fd, bool cloexec) { - int flags = fcntl(fd, F_GETFD); - if (flags == -1) { - wlr_log_errno(WLR_ERROR, "fcntl failed"); - return false; - } - if (cloexec) { - flags = flags | FD_CLOEXEC; - } else { - flags = flags & ~FD_CLOEXEC; - } - if (fcntl(fd, F_SETFD, flags) == -1) { - wlr_log_errno(WLR_ERROR, "fcntl failed"); - return false; - } - return true; -} - static int open_socket(struct sockaddr_un *addr, size_t path_size) { int fd, rc; socklen_t size = offsetof(struct sockaddr_un, sun_path) + path_size + 1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/xwayland/sockets.h new/wlroots-0.20.2/xwayland/sockets.h --- old/wlroots-0.20.1/xwayland/sockets.h 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/xwayland/sockets.h 2026-07-07 23:46:09.000000000 +0200 @@ -3,7 +3,6 @@ #include <stdbool.h> -bool set_cloexec(int fd, bool cloexec); void unlink_display_sockets(int display); int open_display_sockets(int socks[2]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.20.1/xwayland/xwm.c new/wlroots-0.20.2/xwayland/xwm.c --- old/wlroots-0.20.1/xwayland/xwm.c 2026-05-19 22:56:13.000000000 +0200 +++ new/wlroots-0.20.2/xwayland/xwm.c 2026-07-07 23:46:09.000000000 +0200 @@ -630,6 +630,7 @@ 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); @@ -659,7 +660,7 @@ } 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); @@ -667,6 +668,7 @@ if (len > 0 && instance_len < len) { surface->instance = strndup(class, instance_len); class += instance_len + 1; + len -= instance_len + 1; } else { surface->instance = NULL; } @@ -690,7 +692,7 @@ } 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 +721,7 @@ 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 +736,7 @@ } 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,8 +808,12 @@ } struct wlr_xwayland_surface *found_parent = NULL; - 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; @@ -837,9 +843,9 @@ return; } - 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; + const xcb_atom_t *atoms = xcb_get_property_value(reply); + 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) { @@ -864,9 +870,9 @@ return; } - 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; + const xcb_atom_t *atoms = xcb_get_property_value(reply); + 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) { @@ -893,7 +899,7 @@ } 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; @@ -923,7 +929,7 @@ free(xsurface->size_hints); xsurface->size_hints = NULL; - if (reply->value_len == 0) { + if (xcb_get_property_value_length(reply) == 0) { return; } @@ -970,18 +976,19 @@ 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; } - 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,31 +1036,32 @@ struct wlr_xwayland_surface *xsurface, xcb_get_property_reply_t *reply) { xsurface->fullscreen = 0; - 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]) { + const xcb_atom_t *atoms = xcb_get_property_value(reply); + 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 (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; } } @@ -1459,15 +1467,31 @@ 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; } - /* Check if we got notified after wayland surface create event */ + 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]; + + // 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) { + 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 {
