From 5b27a93f58671b7546414cfff673179c3ff0550f Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Tue, 26 Apr 2022 14:37:10 +0100 Subject: tdf#140272 gtk3: fix crash with dnd using touch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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/+/133444 Tested-by: Jenkins Reviewed-by: Caolán McNamara --- vcl/unx/gtk3/gtkframe.cxx | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) (limited to 'vcl/unx/gtk3/gtkframe.cxx') diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx index 35e761ede5fd..0a2ad6dc0df3 100644 --- a/vcl/unx/gtk3/gtkframe.cxx +++ b/vcl/unx/gtk3/gtkframe.cxx @@ -5813,16 +5813,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(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); -- cgit