From d6624b0a756e8bb4e4617a40d4ba620d465546e2 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Mon, 15 Sep 2014 15:32:31 -0400 Subject: [PATCH] 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 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 48d4cf6a5..6ea437193 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); } }