[mutter] wayland/data-device: Clear existing data device resource from list



commit 96f2da9fb03d9fbbbbf0e2e11e310911d0c64db2
Author: Robert Mader <robert mader posteo de>
Date:   Sun Apr 25 19:03:38 2021 +0200

    wayland/data-device: Clear existing data device resource from list
    
    Compositor behaviour when calling `wl_data_device_manager_get_data_device`
    for the same seat multiple times is not very clearly defined in
    the spec and both Mutter and Weston currently don't handle
    the DnD case properly.
    
    While Weston handles DnD only for the last created data device,
    Mutter, because of some internal reshuffling, ends up toggling
    between two devices.
    
    Properly handling this case requires some bigger changes. So
    in order to behave predictable and in line with Weston,
    only take the last created data device into account while
    still keeping the previous created ones around.
    
    The main affect client here is Firefox, which gets very
    confused by the toggling behaviour and becomes more stable
    with this patch.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1841>

 src/wayland/meta-wayland-data-device.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
---
diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c
index 61b4435d42..dd9c162e77 100644
--- a/src/wayland/meta-wayland-data-device.c
+++ b/src/wayland/meta-wayland-data-device.c
@@ -1016,9 +1016,19 @@ get_data_device (struct wl_client *client,
 {
   MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
   struct wl_resource *cr;
+  struct wl_resource *data_device_resource;
 
   cr = wl_resource_create (client, &wl_data_device_interface, wl_resource_get_version (manager_resource), 
id);
   wl_resource_set_implementation (cr, &data_device_interface, &seat->data_device, unbind_resource);
+
+  data_device_resource =
+    wl_resource_find_for_client (&seat->data_device.resource_list, client);
+  if (data_device_resource)
+    {
+      wl_list_remove (wl_resource_get_link (data_device_resource));
+      wl_list_init (wl_resource_get_link (data_device_resource));
+    }
+
   wl_list_insert (&seat->data_device.resource_list, wl_resource_get_link (cr));
 
   ensure_owners_changed_handler_connected (&seat->data_device);


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