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 e5af790acb)
This commit is contained in:
Carlos Garnacho 2019-11-20 00:32:21 +01:00
parent edb618b2a4
commit 7e741fe2d2

View File

@ -1129,8 +1129,6 @@ drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was)
MetaWaylandDragGrab *drag_grab = data; MetaWaylandDragGrab *drag_grab = data;
drag_grab->drag_data_source = NULL; 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); 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; 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 void
meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device, meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device,
MetaWaylandDataSource *source) MetaWaylandDataSource *source)
@ -1600,14 +1608,20 @@ meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device,
return; return;
if (data_device->dnd_data_source) 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; data_device->dnd_data_source = source;
if (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 void