Merge branch 'backport-0.20.2' into '0.20'

0.20.2 backports

See merge request wlroots/wlroots!5375
This commit is contained in:
Simon Zeni 2026-06-13 08:07:25 -04:00
commit 6419e2f411
5 changed files with 76 additions and 43 deletions

View file

@ -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; uint64_t old_active = scene_buffer->active_outputs;
scene_buffer->active_outputs = active_outputs; scene_buffer->active_outputs = active_outputs;

View file

@ -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 and must be retrieved with the DND_TYPE_LIST property
data.data32[1] |= 1; 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; size_t i = 0;
char **mime_type_ptr; char **mime_type_ptr;
wl_array_for_each(mime_type_ptr, mime_types) { 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, XCB_ATOM_ATOM,
32, // format 32, // format
n, targets); n, targets);
free(targets);
} }
xwm_dnd_send_event(xwm, xwm->atoms[DND_ENTER], &data); xwm_dnd_send_event(xwm, xwm->atoms[DND_ENTER], &data);

View file

@ -103,7 +103,7 @@ static int write_selection_property_to_wl_client(int fd, uint32_t mask,
void *data) { void *data) {
struct wlr_xwm_selection_transfer *transfer = 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) - int remainder = xcb_get_property_value_length(transfer->property_reply) -
transfer->property_start; transfer->property_start;
@ -343,8 +343,9 @@ static bool source_get_targets(struct wlr_xwm_selection *selection,
return false; 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++) { 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; char *mime_type = NULL;
if (value[i] == xwm->atoms[UTF8_STRING]) { if (value[i] == xwm->atoms[UTF8_STRING]) {

View file

@ -336,7 +336,11 @@ static void xwm_selection_send_targets(struct wlr_xwm_selection *selection,
} }
size_t n = 2 + mime_types->size / sizeof(char *); 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[0] = xwm->atoms[TIMESTAMP];
targets[1] = xwm->atoms[TARGETS]; targets[1] = xwm->atoms[TARGETS];
@ -356,6 +360,8 @@ static void xwm_selection_send_targets(struct wlr_xwm_selection *selection,
32, // format 32, // format
n, targets); n, targets);
free(targets);
xwm_selection_send_notify(selection->xwm, req, true); xwm_selection_send_notify(selection->xwm, req, true);
} }

View file

@ -630,6 +630,7 @@ static void xwayland_surface_destroy(struct wlr_xwayland_surface *xsurface) {
wl_list_remove(&child->parent_link); wl_list_remove(&child->parent_link);
wl_list_init(&child->parent_link); wl_list_init(&child->parent_link);
child->parent = NULL; child->parent = NULL;
wl_signal_emit_mutable(&child->events.set_parent, NULL);
} }
wl_list_remove(&xsurface->unpaired_link); wl_list_remove(&xsurface->unpaired_link);
@ -659,7 +660,7 @@ static void read_surface_class(struct wlr_xwm *xwm,
} }
size_t len = xcb_get_property_value_length(reply); 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 // Unpack two sequentially stored strings: instance, class
size_t instance_len = strnlen(class, len); size_t instance_len = strnlen(class, len);
@ -667,6 +668,7 @@ static void read_surface_class(struct wlr_xwm *xwm,
if (len > 0 && instance_len < len) { if (len > 0 && instance_len < len) {
surface->instance = strndup(class, instance_len); surface->instance = strndup(class, instance_len);
class += instance_len + 1; class += instance_len + 1;
len -= instance_len + 1;
} else { } else {
surface->instance = NULL; surface->instance = NULL;
} }
@ -690,7 +692,7 @@ static void read_surface_startup_id(struct wlr_xwm *xwm,
} }
size_t len = xcb_get_property_value_length(reply); 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); free(xsurface->startup_id);
if (len > 0) { if (len > 0) {
@ -719,7 +721,7 @@ static void read_surface_opacity(struct wlr_xwm *xwm,
return; return;
} }
uint32_t *val = xcb_get_property_value(reply); const uint32_t *val = xcb_get_property_value(reply);
xsurface->opacity = (double)*val / UINT32_MAX; xsurface->opacity = (double)*val / UINT32_MAX;
wl_signal_emit_mutable(&xsurface->events.set_opacity, NULL); wl_signal_emit_mutable(&xsurface->events.set_opacity, NULL);
} }
@ -734,7 +736,7 @@ static void read_surface_role(struct wlr_xwm *xwm,
} }
size_t len = xcb_get_property_value_length(reply); 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); free(xsurface->role);
if (len > 0) { if (len > 0) {
@ -806,8 +808,12 @@ static void read_surface_parent(struct wlr_xwm *xwm,
} }
struct wlr_xwayland_surface *found_parent = NULL; struct wlr_xwayland_surface *found_parent = NULL;
xcb_window_t *xid = xcb_get_property_value(reply); if (reply->type != XCB_ATOM_NONE) {
if (reply->type != XCB_ATOM_NONE && xid != NULL) { 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); found_parent = lookup_surface(xwm, *xid);
if (!has_parent(found_parent, xsurface)) { if (!has_parent(found_parent, xsurface)) {
xsurface->parent = found_parent; xsurface->parent = found_parent;
@ -837,9 +843,9 @@ static void read_surface_window_type(struct wlr_xwm *xwm,
return; 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_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]);
size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; size_t atoms_size = sizeof(atoms[0]) * atoms_len;
free(xsurface->window_type); free(xsurface->window_type);
if (atoms_len > 0) { if (atoms_len > 0) {
@ -864,9 +870,9 @@ static void read_surface_protocols(struct wlr_xwm *xwm,
return; 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_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]);
size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; size_t atoms_size = sizeof(atoms[0]) * atoms_len;
free(xsurface->protocols); free(xsurface->protocols);
if (atoms_len > 0) { if (atoms_len > 0) {
@ -893,7 +899,7 @@ static void read_surface_hints(struct wlr_xwm *xwm,
} }
free(xsurface->hints); free(xsurface->hints);
if (reply->value_len > 0) { if (xcb_get_property_value_length(reply) > 0) {
xsurface->hints = calloc(1, sizeof(*xsurface->hints)); xsurface->hints = calloc(1, sizeof(*xsurface->hints));
if (xsurface->hints == NULL) { if (xsurface->hints == NULL) {
return; return;
@ -923,7 +929,7 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm,
free(xsurface->size_hints); free(xsurface->size_hints);
xsurface->size_hints = NULL; xsurface->size_hints = NULL;
if (reply->value_len == 0) { if (xcb_get_property_value_length(reply) == 0) {
return; return;
} }
@ -970,18 +976,19 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm,
static void read_surface_motif_hints(struct wlr_xwm *xwm, static void read_surface_motif_hints(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) {
if (reply->value_len == 0) { if (xcb_get_property_value_length(reply) == 0) {
xsurface->decorations = 0; xsurface->decorations = 0;
wl_signal_emit_mutable(&xsurface->events.set_decorations, NULL); wl_signal_emit_mutable(&xsurface->events.set_decorations, NULL);
return; 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"); wlr_log(WLR_DEBUG, "Invalid MOTIF_WM_HINTS property type");
return; return;
} }
uint32_t *motif_hints = xcb_get_property_value(reply);
if (motif_hints[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) { if (motif_hints[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) {
xsurface->decorations = WLR_XWAYLAND_SURFACE_DECORATIONS_ALL; xsurface->decorations = WLR_XWAYLAND_SURFACE_DECORATIONS_ALL;
uint32_t decorations = motif_hints[MWM_HINTS_DECORATIONS_FIELD]; uint32_t decorations = motif_hints[MWM_HINTS_DECORATIONS_FIELD];
@ -1029,31 +1036,32 @@ 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) {
xsurface->fullscreen = 0; xsurface->fullscreen = 0;
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++) { uint32_t atoms_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]);
if (atom[i] == xwm->atoms[NET_WM_STATE_MODAL]) { for (uint32_t i = 0; i < atoms_len; i++) {
if (atoms[i] == xwm->atoms[NET_WM_STATE_MODAL]) {
xsurface->modal = true; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; xsurface->demands_attention = true;
} }
} }
@ -1459,15 +1467,31 @@ static void xwm_handle_surface_id_message(struct wlr_xwm *xwm,
struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->window); struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->window);
if (xsurface == NULL) { if (xsurface == NULL) {
wlr_log(WLR_DEBUG, 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); ev->window);
return; 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]; 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 = struct wl_resource *resource =
wl_client_get_object(xwm->xwayland->server->client, id); wl_client_get_object(xwm->xwayland->server->client, id);
if (resource) { 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); struct wlr_surface *surface = wlr_surface_from_resource(resource);
xwayland_surface_associate(xwm, xsurface, surface); xwayland_surface_associate(xwm, xsurface, surface);
} else { } else {