1
0
Fork 0

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
This commit is contained in:
Owen W. Taylor 2014-09-15 15:32:31 -04:00
parent 9c465a2d5a
commit d6624b0a75

View file

@ -79,26 +79,40 @@ typedef struct {
guint later_id; guint later_id;
} AssociateWindowWithSurfaceOp; } AssociateWindowWithSurfaceOp;
static void associate_window_with_surface_window_unmanaged (MetaWindow *window,
AssociateWindowWithSurfaceOp *op);
static void static void
associate_window_with_surface_window_destroyed (gpointer user_data, associate_window_with_surface_op_free (AssociateWindowWithSurfaceOp *op)
GObject *obj)
{ {
AssociateWindowWithSurfaceOp *op = user_data; if (op->later_id != 0)
meta_later_remove (op->later_id); 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); g_free (op);
} }
static void
associate_window_with_surface_window_unmanaged (MetaWindow *window,
AssociateWindowWithSurfaceOp *op)
{
associate_window_with_surface_op_free (op);
}
static gboolean static gboolean
associate_window_with_surface_later (gpointer user_data) associate_window_with_surface_later (gpointer user_data)
{ {
AssociateWindowWithSurfaceOp *op = user_data; AssociateWindowWithSurfaceOp *op = user_data;
op->later_id = 0;
if (!associate_window_with_surface_id (op->manager, op->window, op->surface_id)) if (!associate_window_with_surface_id (op->manager, op->window, op->surface_id))
{ {
/* Not here? Oh well... nothing we can do */ /* Not here? Oh well... nothing we can do */
g_warning ("Unknown surface ID %d (from window %s)", op->surface_id, op->window->desc); 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; return G_SOURCE_REMOVE;
} }
@ -125,7 +139,8 @@ meta_xwayland_handle_wl_surface_id (MetaWindow *window,
op, op,
NULL); 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);
} }
} }