[mutter] Cleanup xwayland/wayland window association from the "unmanage" signal



commit d6624b0a756e8bb4e4617a40d4ba620d465546e2
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Mon Sep 15 15:32:31 2014 -0400

    Cleanup xwayland/wayland window association from the "unmanage" signal
    
    Windows can be freed at some point after they are unmanaged - because
    there is an effect in progress, because a language binding is holding
    a reference. Therefore, we need to clean up the later to associate
    the xwayland and wayland windows deterministically in an "unamanaged"
    handler.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=736694

 src/wayland/meta-xwayland.c |   29 ++++++++++++++++++++++-------
 1 files changed, 22 insertions(+), 7 deletions(-)
---
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 48d4cf6..6ea4371 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -79,26 +79,40 @@ typedef struct {
   guint later_id;
 } AssociateWindowWithSurfaceOp;
 
+static void associate_window_with_surface_window_unmanaged (MetaWindow                   *window,
+                                                            AssociateWindowWithSurfaceOp *op);
 static void
-associate_window_with_surface_window_destroyed (gpointer  user_data,
-                                                GObject  *obj)
+associate_window_with_surface_op_free (AssociateWindowWithSurfaceOp *op)
 {
-  AssociateWindowWithSurfaceOp *op = user_data;
-  meta_later_remove (op->later_id);
+  if (op->later_id != 0)
+    meta_later_remove (op->later_id);
+  g_signal_handlers_disconnect_by_func (op->window,
+                                        (gpointer) associate_window_with_surface_window_unmanaged,
+                                        op);
   g_free (op);
 }
 
+static void
+associate_window_with_surface_window_unmanaged (MetaWindow                   *window,
+                                                AssociateWindowWithSurfaceOp *op)
+{
+  associate_window_with_surface_op_free (op);
+}
+
 static gboolean
 associate_window_with_surface_later (gpointer user_data)
 {
   AssociateWindowWithSurfaceOp *op = user_data;
+
+  op->later_id = 0;
+
   if (!associate_window_with_surface_id (op->manager, op->window, op->surface_id))
     {
       /* Not here? Oh well... nothing we can do */
       g_warning ("Unknown surface ID %d (from window %s)", op->surface_id, op->window->desc);
     }
-  g_object_weak_unref (G_OBJECT (op->window), associate_window_with_surface_window_destroyed, op);
-  g_free (op);
+
+  associate_window_with_surface_op_free (op);
 
   return G_SOURCE_REMOVE;
 }
@@ -125,7 +139,8 @@ meta_xwayland_handle_wl_surface_id (MetaWindow *window,
                                      op,
                                      NULL);
 
-      g_object_weak_ref (G_OBJECT (op->window), associate_window_with_surface_window_destroyed, op);
+      g_signal_connect (op->window, "unmanaged",
+                        G_CALLBACK (associate_window_with_surface_window_unmanaged), op);
     }
 }
 


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