vcl/unx/gtk3/gtkframe.cxx |   43 +++++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

New commits:
commit 8bf70e7af7ae596edf7610cdfc8a728801dd259a
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Tue Apr 26 14:37:10 2022 +0100
Commit:     Adolfo Jayme Barrientos <fit...@ubuntu.com>
CommitDate: Mon May 2 09:03:52 2022 +0200

    tdf#140272 gtk3: fix crash with dnd using touch
    
    gdk_wayland_drag_context_manage_dnd needs
    gdk_device_window_at_position(device, ...)
    to succeed
    
    similar to the problem of https://gitlab.gnome.org/GNOME/gtk/-/issues/1080
    
    Change-Id: I2e1956b40a622b1d74d3aef3b5fac654fc1256eb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133409
    Tested-by: Jenkins
    Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com>

diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx
index 8864a60cc50d..c6fb8ac14ac1 100644
--- a/vcl/unx/gtk3/gtkframe.cxx
+++ b/vcl/unx/gtk3/gtkframe.cxx
@@ -5815,16 +5815,39 @@ void GtkSalFrame::startDrag(const 
css::datatransfer::dnd::DragGestureEvent& rEve
     aFakeEvent.type = GDK_BUTTON_PRESS;
     aFakeEvent.button.window = widget_get_surface(getMouseEventWidget());
     aFakeEvent.button.time = GDK_CURRENT_TIME;
-    GdkDeviceManager* pDeviceManager = 
gdk_display_get_device_manager(getGdkDisplay());
-    aFakeEvent.button.device = 
gdk_device_manager_get_client_pointer(pDeviceManager);
-
-    GdkDragContext *pDrag = 
gtk_drag_begin_with_coordinates(getMouseEventWidget(),
-                                                            pTargetList,
-                                                            sourceActions,
-                                                            nDragButton,
-                                                            &aFakeEvent,
-                                                            rEvent.DragOriginX,
-                                                            
rEvent.DragOriginY);
+
+    aFakeEvent.button.device = gtk_get_current_event_device();
+    // if no current event to determine device, or (tdf#140272) the device 
will be unsuitable then find an
+    // appropiate device to use.
+    if (!aFakeEvent.button.device || 
!gdk_device_get_window_at_position(aFakeEvent.button.device, nullptr, nullptr))
+    {
+        GdkDeviceManager* pDeviceManager = 
gdk_display_get_device_manager(getGdkDisplay());
+        GList* pDevices = gdk_device_manager_list_devices(pDeviceManager, 
GDK_DEVICE_TYPE_MASTER);
+        for (GList* pEntry = pDevices; pEntry; pEntry = pEntry->next)
+        {
+            GdkDevice* pDevice = static_cast<GdkDevice*>(pEntry->data);
+            if (gdk_device_get_source(pDevice) == GDK_SOURCE_KEYBOARD)
+                continue;
+            if (gdk_device_get_window_at_position(pDevice, nullptr, nullptr))
+            {
+                aFakeEvent.button.device = pDevice;
+                break;
+            }
+        }
+        g_list_free(pDevices);
+    }
+
+    GdkDragContext *pDrag;
+    if (!aFakeEvent.button.device || 
!gdk_device_get_window_at_position(aFakeEvent.button.device, nullptr, nullptr))
+        pDrag = nullptr;
+    else
+        pDrag = gtk_drag_begin_with_coordinates(getMouseEventWidget(),
+                                                pTargetList,
+                                                sourceActions,
+                                                nDragButton,
+                                                &aFakeEvent,
+                                                rEvent.DragOriginX,
+                                                rEvent.DragOriginY);
 
     gtk_target_list_unref(pTargetList);
 

Reply via email to