From b1587f0716e0f05128fe69441f2548d81530f7a1 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