[mutter] compositor: reset top_window_actor and remove it from windows when destroyed



commit b1587f0716e0f05128fe69441f2548d81530f7a1
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Wed Nov 29 18:05:27 2017 -0500

    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 files changed, 20 insertions(+), 3 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 0eb54fd..ff919e6 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]