From 7e741fe2d2d98fec2d47b60dcafe7a8cc45d93be Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 20 Nov 2019 00:32:21 +0100 Subject: [PATCH] wayland: Move "ownership" of the DnD selection source to the data device On wl_data_source destruction we used to indirectly unset the DnD selection owner via the wl_resource destructor triggering the destruction of the MetaWaylandDataSource, which would be caught through the weak ref set by the MetaWaylandDragGrab. This works as long as the grab is held, however we have a window between the button being released and the drop site replying with wl_data_offer.finish that the MetaWaylandDataSource is alive, but its destruction wouldn't result in the call chain above to unsetting the DnD source. In other selection sources, we let the MetaWaylandDataDevice hold the "ownership" of the MetaWaylandDataSource, and its weak ref functions unset the respective MetaSelection owners. Do the same here, so the MetaWaylandDataSource destruction is listened for all its lifetime. Closes: https://gitlab.gnome.org/GNOME/mutter/issues/591 (cherry picked from commit e5af790acb979ae9c8a0509052a42208c67639a6) --- src/wayland/meta-wayland-data-device.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index e5018407d..53477a533 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -1129,8 +1129,6 @@ drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was) MetaWaylandDragGrab *drag_grab = data; drag_grab->drag_data_source = NULL; - meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL); - unset_selection_source (&drag_grab->seat->data_device, META_SELECTION_DND); data_device_end_drag_grab (drag_grab); } @@ -1592,6 +1590,16 @@ meta_wayland_data_device_get_drag_dest_funcs (void) return &meta_wayland_drag_dest_funcs; } +static void +dnd_data_source_destroyed (gpointer data, + GObject *object_was_here) +{ + MetaWaylandDataDevice *data_device = data; + + data_device->dnd_data_source = NULL; + unset_selection_source (data_device, META_SELECTION_DND); +} + void meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device, MetaWaylandDataSource *source) @@ -1600,14 +1608,20 @@ meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device, return; if (data_device->dnd_data_source) - g_object_remove_weak_pointer (G_OBJECT (data_device->dnd_data_source), - (gpointer *)&data_device->dnd_data_source); + { + g_object_weak_unref (G_OBJECT (data_device->dnd_data_source), + dnd_data_source_destroyed, + data_device); + } data_device->dnd_data_source = source; if (source) - g_object_add_weak_pointer (G_OBJECT (data_device->dnd_data_source), - (gpointer *)&data_device->dnd_data_source); + { + g_object_weak_ref (G_OBJECT (source), + dnd_data_source_destroyed, + data_device); + } } void