diff options
author | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2017-11-29 18:05:27 -0500 |
---|---|---|
committer | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2017-11-30 22:53:26 -0500 |
commit | b1587f0716e0f05128fe69441f2548d81530f7a1 (patch) | |
tree | bf2e898f865d0801a524dcb6033027ec782a41ae | |
parent | 93e450f37c0db6892c2f006f077ed674cec052fb (diff) | |
download | mutter-b1587f0716e0f05128fe69441f2548d81530f7a1.tar.gz |
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
-rw-r--r-- | src/compositor/compositor.c | 23 |
1 files 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 |