diff options
author | Caolán McNamara <caolanm@redhat.com> | 2022-04-26 14:37:10 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2022-04-26 17:15:56 +0200 |
commit | 5b27a93f58671b7546414cfff673179c3ff0550f (patch) | |
tree | 01d83808bb3093b301a81d01c1afc644b9a20d9e /vcl | |
parent | a8d01742e98d29a57be6d990b7331f789bc3a5ee (diff) |
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/+/133444
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/unx/gtk3/gtkframe.cxx | 43 |
1 files changed, 33 insertions, 10 deletions
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<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); |