From 8a5b5e6f28dae650df36a271213655b8bdf52dbf Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 23 Jun 2023 14:33:26 +0200 Subject: [PATCH] compositor: listen to role_resource destroy signal Call wlr_surface_destroy_role_object() when the role_resource is destroyed. --- include/wlr/types/wlr_compositor.h | 3 +++ types/wlr_compositor.c | 12 ++++++++++++ types/wlr_input_method_v2.c | 10 +--------- types/wlr_layer_shell_v1.c | 10 +--------- types/wlr_session_lock_v1.c | 11 +---------- types/wlr_subcompositor.c | 9 +-------- xwayland/shell.c | 10 +--------- 7 files changed, 20 insertions(+), 45 deletions(-) diff --git a/include/wlr/types/wlr_compositor.h b/include/wlr/types/wlr_compositor.h index 40ea7e9f..ffb56896 100644 --- a/include/wlr/types/wlr_compositor.h +++ b/include/wlr/types/wlr_compositor.h @@ -199,6 +199,7 @@ struct wlr_surface { // private state struct wl_listener renderer_destroy; + struct wl_listener role_resource_destroy; struct { int32_t scale; @@ -246,6 +247,8 @@ bool wlr_surface_set_role(struct wlr_surface *surface, const struct wlr_surface_ /** * Set the role object for this surface. The surface must have a role and * no already set role object. + * + * wlr_surface_destroy_role_object() is called when the resource is destroyed. */ void wlr_surface_set_role_object(struct wlr_surface *surface, struct wl_resource *role_resource); diff --git a/types/wlr_compositor.c b/types/wlr_compositor.c index 626fc9d8..80c0495b 100644 --- a/types/wlr_compositor.c +++ b/types/wlr_compositor.c @@ -648,6 +648,7 @@ static void surface_handle_resource_destroy(struct wl_resource *resource) { } wl_list_remove(&surface->renderer_destroy.link); + wl_list_remove(&surface->role_resource_destroy.link); surface_state_finish(&surface->pending); surface_state_finish(&surface->current); pixman_region32_fini(&surface->buffer_damage); @@ -714,6 +715,8 @@ static struct wlr_surface *surface_create(struct wl_client *client, wl_list_init(&surface->renderer_destroy.link); } + wl_list_init(&surface->role_resource_destroy.link); + return surface; } @@ -790,12 +793,19 @@ bool wlr_surface_set_role(struct wlr_surface *surface, const struct wlr_surface_ return true; } +static void surface_handle_role_resource_destroy(struct wl_listener *listener, void *data) { + struct wlr_surface *surface = wl_container_of(listener, surface, role_resource_destroy); + wlr_surface_destroy_role_object(surface); +} + void wlr_surface_set_role_object(struct wlr_surface *surface, struct wl_resource *role_resource) { assert(surface->role != NULL); assert(!surface->role->no_object); assert(surface->role_resource == NULL); assert(role_resource != NULL); surface->role_resource = role_resource; + surface->role_resource_destroy.notify = surface_handle_role_resource_destroy; + wl_resource_add_destroy_listener(role_resource, &surface->role_resource_destroy); } void wlr_surface_destroy_role_object(struct wlr_surface *surface) { @@ -807,6 +817,8 @@ void wlr_surface_destroy_role_object(struct wlr_surface *surface) { surface->role->destroy(surface); } surface->role_resource = NULL; + wl_list_remove(&surface->role_resource_destroy.link); + wl_list_init(&surface->role_resource_destroy.link); } uint32_t wlr_surface_lock_pending(struct wlr_surface *surface) { diff --git a/types/wlr_input_method_v2.c b/types/wlr_input_method_v2.c index 3658104e..155d6cb2 100644 --- a/types/wlr_input_method_v2.c +++ b/types/wlr_input_method_v2.c @@ -175,14 +175,6 @@ struct wlr_input_popup_surface_v2 *wlr_input_popup_surface_v2_try_from_wlr_surfa return popup_surface_from_resource(surface->role_resource); } -static void popup_resource_destroy(struct wl_resource *resource) { - struct wlr_input_popup_surface_v2 *popup_surface = - popup_surface_from_resource(resource); - if (popup_surface != NULL) { - wlr_surface_destroy_role_object(popup_surface->surface); - } -} - static void popup_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); @@ -225,7 +217,7 @@ static void im_get_input_popup_surface(struct wl_client *client, } wl_resource_set_implementation(popup_resource, &input_popup_impl, - popup_surface, popup_resource_destroy); + popup_surface, NULL); wlr_surface_set_role_object(surface, popup_resource); diff --git a/types/wlr_layer_shell_v1.c b/types/wlr_layer_shell_v1.c index 5e6e83eb..69091f96 100644 --- a/types/wlr_layer_shell_v1.c +++ b/types/wlr_layer_shell_v1.c @@ -264,14 +264,6 @@ static const struct zwlr_layer_surface_v1_interface layer_surface_implementation .set_layer = layer_surface_set_layer, }; -static void layer_surface_resource_destroy(struct wl_resource *resource) { - struct wlr_layer_surface_v1 *surface = - wlr_layer_surface_v1_from_resource(resource); - if (surface != NULL) { - wlr_surface_destroy_role_object(surface->surface); - } -} - uint32_t wlr_layer_surface_v1_configure(struct wlr_layer_surface_v1 *surface, uint32_t width, uint32_t height) { struct wl_display *display = @@ -443,7 +435,7 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client, wlr_log(WLR_DEBUG, "new layer_surface %p (res %p)", surface, surface->resource); wl_resource_set_implementation(surface->resource, - &layer_surface_implementation, surface, layer_surface_resource_destroy); + &layer_surface_implementation, surface, NULL); wlr_surface_set_role_object(wlr_surface, surface->resource); } diff --git a/types/wlr_session_lock_v1.c b/types/wlr_session_lock_v1.c index cf79cd24..3ef6f8c2 100644 --- a/types/wlr_session_lock_v1.c +++ b/types/wlr_session_lock_v1.c @@ -198,14 +198,6 @@ static void lock_surface_handle_output_destroy(struct wl_listener *listener, wlr_surface_destroy_role_object(lock_surface->surface); } -static void lock_surface_resource_destroy(struct wl_resource *resource) { - struct wlr_session_lock_surface_v1 *lock_surface = - lock_surface_from_resource(resource); - if (lock_surface != NULL) { - wlr_surface_destroy_role_object(lock_surface->surface); - } -} - static void lock_handle_get_lock_surface(struct wl_client *client, struct wl_resource *lock_resource, uint32_t id, struct wl_resource *surface_resource, @@ -226,8 +218,7 @@ static void lock_handle_get_lock_surface(struct wl_client *client, // Leave the lock surface resource inert for now, we will set the // user data at the end of this function if everything is successful. wl_resource_set_implementation(lock_surface_resource, - &lock_surface_implementation, NULL, - lock_surface_resource_destroy); + &lock_surface_implementation, NULL, NULL); struct wlr_session_lock_v1 *lock = lock_from_resource(lock_resource); if (lock == NULL) { diff --git a/types/wlr_subcompositor.c b/types/wlr_subcompositor.c index 8270c86e..96bedb69 100644 --- a/types/wlr_subcompositor.c +++ b/types/wlr_subcompositor.c @@ -37,13 +37,6 @@ static struct wlr_subsurface *subsurface_from_resource( return wl_resource_get_user_data(resource); } -static void subsurface_resource_destroy(struct wl_resource *resource) { - struct wlr_subsurface *subsurface = subsurface_from_resource(resource); - if (subsurface != NULL) { - wlr_surface_destroy_role_object(subsurface->surface); - } -} - static void subsurface_handle_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); @@ -342,7 +335,7 @@ static void subcompositor_handle_get_subsurface(struct wl_client *client, return; } wl_resource_set_implementation(subsurface->resource, - &subsurface_implementation, subsurface, subsurface_resource_destroy); + &subsurface_implementation, subsurface, NULL); wlr_surface_set_role_object(surface, subsurface->resource); diff --git a/xwayland/shell.c b/xwayland/shell.c index 28f572d3..87008c6b 100644 --- a/xwayland/shell.c +++ b/xwayland/shell.c @@ -91,14 +91,6 @@ static void xwl_surface_handle_surface_destroy(struct wl_listener *listener, wlr_surface_destroy_role_object(xwl_surface->surface); } -static void xwl_surface_handle_resource_destroy(struct wl_resource *resource) { - struct wlr_xwayland_surface_v1 *xwl_surface = - xwl_surface_from_resource(resource); - if (xwl_surface != NULL) { - wlr_surface_destroy_role_object(xwl_surface->surface); - } -} - static void shell_handle_get_xwayland_surface(struct wl_client *client, struct wl_resource *shell_resource, uint32_t id, struct wl_resource *surface_resource) { @@ -129,7 +121,7 @@ static void shell_handle_get_xwayland_surface(struct wl_client *client, return; } wl_resource_set_implementation(xwl_surface->resource, &xwl_surface_impl, - xwl_surface, xwl_surface_handle_resource_destroy); + xwl_surface, NULL); wlr_surface_set_role_object(surface, xwl_surface->resource);