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;
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.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);

View file

@ -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,8 +343,9 @@ static bool source_get_targets(struct wlr_xwm_selection *selection,
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);
for (uint32_t i = 0; i < value_len; i++) {
char *mime_type = NULL;
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 *);
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);
}

View file

@ -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);
@ -659,7 +660,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);
@ -667,6 +668,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;
}
@ -690,7 +692,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 +721,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 +736,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,8 +808,12 @@ 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);
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 @@ static void read_surface_window_type(struct wlr_xwm *xwm,
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 @@ static void read_surface_protocols(struct wlr_xwm *xwm,
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 @@ 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;
@ -923,7 +929,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;
}
@ -970,18 +976,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;
}
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 @@ 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);
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 @@ 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;
}
/* 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 {