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
This commit is contained in:
Simon Ser 2022-01-20 10:03:31 +01:00 committed by Kirill Primak
parent 7ce966a5d4
commit 1d1b845410
2 changed files with 13 additions and 30 deletions

View file

@ -478,7 +478,7 @@ static void collect_subsurface_damage_iter(struct wlr_surface *surface,
// TODO: untangle from wlr_surface // TODO: untangle from wlr_surface
static void subsurface_parent_commit(struct wlr_subsurface *subsurface) { static void subsurface_parent_commit(struct wlr_subsurface *subsurface) {
struct wlr_surface *surface = subsurface->surface; struct wlr_surface *surface = subsurface->surface;
bool moved = subsurface->current.x != subsurface->pending.x || bool moved = subsurface->current.x != subsurface->pending.x ||
subsurface->current.y != subsurface->pending.y; subsurface->current.y != subsurface->pending.y;
if (subsurface->mapped && moved) { if (subsurface->mapped && moved) {
@ -789,9 +789,6 @@ struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface) {
if (subsurface == NULL) { if (subsurface == NULL) {
break; break;
} }
if (subsurface->parent == NULL) {
return NULL;
}
surface = subsurface->parent; surface = subsurface->parent;
} }
return surface; return surface;

View file

@ -14,10 +14,6 @@ static bool subsurface_is_synchronized(struct wlr_subsurface *subsurface) {
return true; return true;
} }
if (!subsurface->parent) {
return false;
}
if (!wlr_surface_is_subsurface(subsurface->parent)) { if (!wlr_surface_is_subsurface(subsurface->parent)) {
break; 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_destroy.link);
wl_list_remove(&subsurface->surface_client_commit.link); wl_list_remove(&subsurface->surface_client_commit.link);
wl_list_remove(&subsurface->current.link);
if (subsurface->parent) { wl_list_remove(&subsurface->pending.link);
wl_list_remove(&subsurface->current.link); wl_list_remove(&subsurface->parent_destroy.link);
wl_list_remove(&subsurface->pending.link);
wl_list_remove(&subsurface->parent_destroy.link);
}
wl_resource_set_user_data(subsurface->resource, NULL); wl_resource_set_user_data(subsurface->resource, NULL);
if (subsurface->surface) { if (subsurface->surface) {
@ -64,8 +57,8 @@ static const struct wl_subsurface_interface subsurface_implementation;
/** /**
* Get a wlr_subsurface from a wl_subsurface resource. * Get a wlr_subsurface from a wl_subsurface resource.
* *
* Returns NULL if the subsurface is inert (e.g. the wl_surface object got * Returns NULL if the subsurface is inert (e.g. the wl_surface object or the
* destroyed). * parent surface got destroyed).
*/ */
static struct wlr_subsurface *subsurface_from_resource( static struct wlr_subsurface *subsurface_from_resource(
struct wl_resource *resource) { struct wl_resource *resource) {
@ -227,17 +220,12 @@ static void subsurface_consider_map(struct wlr_subsurface *subsurface,
return; return;
} }
if (check_parent) { if (check_parent && wlr_surface_is_subsurface(subsurface->parent)) {
if (subsurface->parent == NULL) { struct wlr_subsurface *parent =
wlr_subsurface_from_wlr_surface(subsurface->parent);
if (parent == NULL || !parent->mapped) {
return; 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 // Now we can map the subsurface
@ -310,11 +298,9 @@ static void subsurface_handle_parent_destroy(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_subsurface *subsurface = struct wlr_subsurface *subsurface =
wl_container_of(listener, subsurface, parent_destroy); wl_container_of(listener, subsurface, parent_destroy);
subsurface_unmap(subsurface); // Once the parent is destroyed, the client has no way to use the
wl_list_remove(&subsurface->current.link); // wl_subsurface object anymore, so we can destroy it.
wl_list_remove(&subsurface->pending.link); subsurface_destroy(subsurface);
wl_list_remove(&subsurface->parent_destroy.link);
subsurface->parent = NULL;
} }
static void subsurface_handle_surface_destroy(struct wl_listener *listener, static void subsurface_handle_surface_destroy(struct wl_listener *listener,