From 1d1b84541015d7b2914bdc69013f2a04548f4321 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 20 Jan 2022 10:03:31 +0100 Subject: [PATCH] subcompositor: destroy subsurface with parent When the parent surface is destroyed, also destroy the child wl_subsurface. No need to handle the wlr_subsurface.parent == NULL case anymore. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/1709 --- types/wlr_compositor.c | 5 +---- types/wlr_subcompositor.c | 38 ++++++++++++-------------------------- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/types/wlr_compositor.c b/types/wlr_compositor.c index 6c4eb61b..e7b922a5 100644 --- a/types/wlr_compositor.c +++ b/types/wlr_compositor.c @@ -478,7 +478,7 @@ static void collect_subsurface_damage_iter(struct wlr_surface *surface, // TODO: untangle from wlr_surface static void subsurface_parent_commit(struct wlr_subsurface *subsurface) { struct wlr_surface *surface = subsurface->surface; - + bool moved = subsurface->current.x != subsurface->pending.x || subsurface->current.y != subsurface->pending.y; if (subsurface->mapped && moved) { @@ -789,9 +789,6 @@ struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface) { if (subsurface == NULL) { break; } - if (subsurface->parent == NULL) { - return NULL; - } surface = subsurface->parent; } return surface; diff --git a/types/wlr_subcompositor.c b/types/wlr_subcompositor.c index e9d53f53..8ee5a949 100644 --- a/types/wlr_subcompositor.c +++ b/types/wlr_subcompositor.c @@ -14,10 +14,6 @@ static bool subsurface_is_synchronized(struct wlr_subsurface *subsurface) { return true; } - if (!subsurface->parent) { - return false; - } - if (!wlr_surface_is_subsurface(subsurface->parent)) { break; } @@ -45,12 +41,9 @@ static void subsurface_destroy(struct wlr_subsurface *subsurface) { wl_list_remove(&subsurface->surface_destroy.link); wl_list_remove(&subsurface->surface_client_commit.link); - - if (subsurface->parent) { - wl_list_remove(&subsurface->current.link); - wl_list_remove(&subsurface->pending.link); - wl_list_remove(&subsurface->parent_destroy.link); - } + wl_list_remove(&subsurface->current.link); + wl_list_remove(&subsurface->pending.link); + wl_list_remove(&subsurface->parent_destroy.link); wl_resource_set_user_data(subsurface->resource, NULL); if (subsurface->surface) { @@ -64,8 +57,8 @@ static const struct wl_subsurface_interface subsurface_implementation; /** * Get a wlr_subsurface from a wl_subsurface resource. * - * Returns NULL if the subsurface is inert (e.g. the wl_surface object got - * destroyed). + * Returns NULL if the subsurface is inert (e.g. the wl_surface object or the + * parent surface got destroyed). */ static struct wlr_subsurface *subsurface_from_resource( struct wl_resource *resource) { @@ -227,17 +220,12 @@ static void subsurface_consider_map(struct wlr_subsurface *subsurface, return; } - if (check_parent) { - if (subsurface->parent == NULL) { + if (check_parent && wlr_surface_is_subsurface(subsurface->parent)) { + struct wlr_subsurface *parent = + wlr_subsurface_from_wlr_surface(subsurface->parent); + if (parent == NULL || !parent->mapped) { return; } - if (wlr_surface_is_subsurface(subsurface->parent)) { - struct wlr_subsurface *parent = - wlr_subsurface_from_wlr_surface(subsurface->parent); - if (parent == NULL || !parent->mapped) { - return; - } - } } // Now we can map the subsurface @@ -310,11 +298,9 @@ static void subsurface_handle_parent_destroy(struct wl_listener *listener, void *data) { struct wlr_subsurface *subsurface = wl_container_of(listener, subsurface, parent_destroy); - subsurface_unmap(subsurface); - wl_list_remove(&subsurface->current.link); - wl_list_remove(&subsurface->pending.link); - wl_list_remove(&subsurface->parent_destroy.link); - subsurface->parent = NULL; + // Once the parent is destroyed, the client has no way to use the + // wl_subsurface object anymore, so we can destroy it. + subsurface_destroy(subsurface); } static void subsurface_handle_surface_destroy(struct wl_listener *listener,