summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (Treviño) <mail@3v1n0.net>2017-11-29 18:05:27 -0500
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2017-11-30 22:53:26 -0500
commitb1587f0716e0f05128fe69441f2548d81530f7a1 (patch)
treebf2e898f865d0801a524dcb6033027ec782a41ae
parent93e450f37c0db6892c2f006f077ed674cec052fb (diff)
downloadmutter-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.c23
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