window-actor/wayland: Remove subsurface actors on dispose

Destroying the window actor also destroys all its children. Subsurfaces
however may get reused. If the client did not unparent them before
the window actor got destroyed, they will be left without actor
which results in a crash.

Unparent all actors of subsurfaces on dispose to avoid that.

Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/1892

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1958>
This commit is contained in:
Robert Mader 2021-08-06 13:09:04 +02:00 committed by Marge Bot
parent f41696b0fc
commit dd416dd3e2

View File

@ -149,10 +149,33 @@ meta_window_actor_wayland_can_freeze_commits (MetaWindowActor *actor)
return FALSE;
}
static void
meta_window_actor_wayland_dispose (GObject *object)
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (object);
MetaSurfaceActor *surface_actor =
meta_window_actor_get_surface (window_actor);
GList *children;
GList *l;
children = clutter_actor_get_children (CLUTTER_ACTOR (window_actor));
for (l = children; l; l = l->next)
{
ClutterActor *child_actor = l->data;
if (META_IS_SURFACE_ACTOR_WAYLAND (child_actor) &&
child_actor != CLUTTER_ACTOR (surface_actor))
clutter_actor_remove_child (CLUTTER_ACTOR (window_actor), child_actor);
}
G_OBJECT_CLASS (meta_window_actor_wayland_parent_class)->dispose (object);
}
static void
meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
{
MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
window_actor_class->assign_surface_actor = meta_window_actor_wayland_assign_surface_actor;
window_actor_class->frame_complete = meta_window_actor_wayland_frame_complete;
@ -163,6 +186,8 @@ meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
window_actor_class->set_frozen = meta_window_actor_wayland_set_frozen;
window_actor_class->update_regions = meta_window_actor_wayland_update_regions;
window_actor_class->can_freeze_commits = meta_window_actor_wayland_can_freeze_commits;
object_class->dispose = meta_window_actor_wayland_dispose;
}
static void