From bf91e2b4ca1ef8b0478d1edec46bd33065457153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 29 Nov 2017 18:05:27 -0500 Subject: [PATCH] compositor: reset top_window_actor and remove it from windows when destroyed When the top window actor is destroyed, we need to make sure that all its references are removed or it could be picked again in next windows sync, causing crashes. Since the window might or might not be destroyed when removed (depending weather animations are in progress over it or not), it's just safer to wait it to be destroyed before cleaning up any of its reference. https://bugzilla.gnome.org/show_bug.cgi?id=791006 --- src/compositor/compositor.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 0eb54fd4e..ff919e6de 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -674,9 +674,6 @@ meta_compositor_remove_window (MetaCompositor *compositor, if (compositor->unredirected_window == window) set_unredirected_window (compositor, NULL); - if (compositor->top_window_actor == window_actor) - compositor->top_window_actor = NULL; - meta_window_actor_destroy (window_actor); } @@ -955,6 +952,16 @@ get_top_visible_window_actor (MetaCompositor *compositor) return NULL; } +static void +on_top_window_actor_destroyed (MetaWindowActor *window_actor, + MetaCompositor *compositor) +{ + compositor->top_window_actor = NULL; + compositor->windows = g_list_remove (compositor->windows, window_actor); + + meta_stack_tracker_queue_sync_stack (compositor->display->screen->stack_tracker); +} + void meta_compositor_sync_stack (MetaCompositor *compositor, GList *stack) @@ -1042,7 +1049,17 @@ meta_compositor_sync_stack (MetaCompositor *compositor, sync_actor_stacking (compositor); + 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 = get_top_visible_window_actor (compositor); + + if (compositor->top_window_actor) + g_signal_connect (compositor->top_window_actor, "destroy", + G_CALLBACK (on_top_window_actor_destroyed), + compositor); } void