From abf80b529e48823e21215a6ccc4653e2c2a4a565 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 24 Nov 2025 16:53:19 +0900 Subject: [PATCH] wlr-foreign-toplevel: avoid wl_resource_find_for_client() If the client application is composed of multiple components and they bind the manager global separately, choosing a single toplevel resource with wl_resource_find_for_client() may result in a component only seeing unknown toplevel handles from another component. Maybe we should track which toplevel handle resource originate from which manager resource so that a component never sees toplevel handles resources from another component, but it's too annoying to implement. --- types/wlr_foreign_toplevel_management_v1.c | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/types/wlr_foreign_toplevel_management_v1.c b/types/wlr_foreign_toplevel_management_v1.c index 15b18000c..c98457a3d 100644 --- a/types/wlr_foreign_toplevel_management_v1.c +++ b/types/wlr_foreign_toplevel_management_v1.c @@ -417,16 +417,17 @@ static void toplevel_resource_send_parent( return; } struct wl_client *client = wl_resource_get_client(toplevel_resource); - struct wl_resource *parent_resource = NULL; if (parent) { - parent_resource = wl_resource_find_for_client(&parent->resources, client); - if (!parent_resource) { - /* don't send an event if this client destroyed the parent handle */ - return; + struct wl_resource *parent_resource; + wl_resource_for_each(parent_resource, &parent->resources) { + if (wl_resource_get_client(parent_resource) == client) { + zwlr_foreign_toplevel_handle_v1_send_parent( + toplevel_resource, parent_resource); + } } + } else { + zwlr_foreign_toplevel_handle_v1_send_parent(toplevel_resource, NULL); } - zwlr_foreign_toplevel_handle_v1_send_parent(toplevel_resource, - parent_resource); } void wlr_foreign_toplevel_handle_v1_set_parent( @@ -624,10 +625,13 @@ static void foreign_toplevel_manager_bind(struct wl_client *client, void *data, } /* Second loop: send details about each toplevel. */ wl_list_for_each_safe(toplevel, tmp, &manager->toplevels, link) { - struct wl_resource *toplevel_resource = - wl_resource_find_for_client(&toplevel->resources, client); - toplevel_send_details_to_toplevel_resource(toplevel, - toplevel_resource); + struct wl_resource *toplevel_resource; + wl_resource_for_each(toplevel_resource, &toplevel->resources) { + if (wl_resource_get_client(toplevel_resource) == client) { + toplevel_send_details_to_toplevel_resource(toplevel, + toplevel_resource); + } + } } }