[mutter/wip/carlosg/fix-dnd-crash: 18/18] wayland: Move "ownership" of the DnD selection source to the data device



commit e5af790acb979ae9c8a0509052a42208c67639a6
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Nov 20 00:32:21 2019 +0100

    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

 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 c83667b16..bee7fb8bc 100644
--- a/src/wayland/meta-wayland-data-device.c
+++ b/src/wayland/meta-wayland-data-device.c
@@ -1138,8 +1138,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);
 }
 
@@ -1577,6 +1575,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)
@@ -1585,14 +1593,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


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