summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2019-04-29 19:57:03 +0000
committerMarco Trevisan <mail@3v1n0.net>2019-05-01 05:10:51 +0000
commit3495a438107e7988bd1a5a089c66fa795a3d5981 (patch)
treefb4b3f87bcac92ebc45e2b3ab533f4488728d459
parent9a795d3d0f5a8568e6f17e274d3f7f0374bd1fc9 (diff)
downloadmutter-3495a438107e7988bd1a5a089c66fa795a3d5981.tar.gz
compositor: Destroy window actors list on destruction
When the compositor is destroyed we should cleanup the list of window actors we created and destroy them. Since all the actors are added to the window_group or top_window_group we can just destroy these containers (together with the feedback_group), and simply free the windows list. This is particularly needed under X11 because before we destroy the display, we might do some cleanups as detaching the surface pixmaps and freeing the damages and if this happens at later point (for example when triggered by garbage collector in gnome-shell), we might crash because the x11 dpy reference is already gone. Destroying the window actors instead, ensures we avoid any further call to X11 related functions and that we release the actors XServer resources. Fixes https://gitlab.gnome.org/GNOME/mutter/issues/576 (cherry picked from commit 7718e67f5c0c78ed93e9ad04e7254b6db70a0337)
-rw-r--r--src/compositor/compositor.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 0854a198b..f47889f43 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -92,6 +92,10 @@ on_presented (ClutterStage *stage,
ClutterFrameInfo *frame_info,
MetaCompositor *compositor);
+static void
+on_top_window_actor_destroyed (MetaWindowActor *window_actor,
+ MetaCompositor *compositor);
+
static gboolean
is_modal (MetaDisplay *display)
{
@@ -134,6 +138,19 @@ meta_compositor_destroy (MetaCompositor *compositor)
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
+ if (compositor->top_window_actor)
+ {
+ g_signal_handlers_disconnect_by_func (compositor->top_window_actor,
+ on_top_window_actor_destroyed,
+ compositor);
+ compositor->top_window_actor = NULL;
+ }
+
+ g_clear_pointer (&compositor->window_group, clutter_actor_destroy);
+ g_clear_pointer (&compositor->top_window_group, clutter_actor_destroy);
+ g_clear_pointer (&compositor->feedback_group, clutter_actor_destroy);
+ g_clear_pointer (&compositor->windows, g_list_free);
+
if (compositor->have_x11_sync_object)
meta_sync_ring_destroy ();
}