diff options
author | Caolán McNamara <caolanm@redhat.com> | 2017-07-27 09:08:02 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2017-07-27 22:44:55 +0200 |
commit | ab273651477d76890fc4268277b52893d89edc0b (patch) | |
tree | 160dfd2847e106b412ea37e0b8141e4524e11602 | |
parent | 8eb05127e8ffcbe4a6bd6eb10b073d015cea34aa (diff) |
gtk3: Resolves: tdf#109277 take modifier key into account for dnd
Change-Id: Id0aa4ced8644ddbee9e1a0453887f07907547aae
(cherry picked from commit 0c840d9bf308464d58a2df8aaa1e61481b5e4f52)
Reviewed-on: https://gerrit.libreoffice.org/40476
Reviewed-by: Michael Stahl <mstahl@redhat.com>
Tested-by: Michael Stahl <mstahl@redhat.com>
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkframe.cxx | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index c02a19093f7d..618b9f17caa6 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -3461,7 +3461,11 @@ gboolean GtkSalFrame::signalDragDrop(GtkWidget* pWidget, GdkDragContext* context // navigator unless this is set. Its unclear really what ACTION_DEFAULT means, // there is a deprecated 'GDK_ACTION_DEFAULT Means nothing, and should not be used' // possible equivalent in gtk. - aEvent.DropAction |= css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT; + // So (tdf#109227) set ACTION_DEFAULT if no modifier key is held down + GdkModifierType mask; + gdk_window_get_pointer(widget_get_window(pWidget), nullptr, nullptr, &mask); + if (!(mask & (GDK_CONTROL_MASK | GDK_SHIFT_MASK))) + aEvent.DropAction |= css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT; aEvent.SourceActions = GdkToVcl(gdk_drag_context_get_actions(context)); css::uno::Reference<css::datatransfer::XTransferable> xTransferable; // For LibreOffice internal D&D we provide the Transferable without Gtk @@ -3533,7 +3537,27 @@ gboolean GtkSalFrame::signalDragMotion(GtkWidget *pWidget, GdkDragContext *conte //inform the original caller of our choice and the callsite can decide //to overrule this choice. i.e. typically here we default to ACTION_MOVE sal_Int8 nSourceActions = GdkToVcl(gdk_drag_context_get_actions(context)); - GdkDragAction eAction = getPreferredDragAction(nSourceActions); + GdkModifierType mask; + gdk_window_get_pointer(widget_get_window(pWidget), nullptr, nullptr, &mask); + + // tdf#109227 if a modifier is held down, default to the matching + // action for that modifier combo, otherwise pick the preferred + // default from the possible source actions + sal_Int8 nNewDropAction = css::datatransfer::dnd::DNDConstants::ACTION_MOVE; + if ((mask & GDK_SHIFT_MASK) && !(mask & GDK_CONTROL_MASK)) + nNewDropAction = css::datatransfer::dnd::DNDConstants::ACTION_MOVE; + else if ((mask & GDK_CONTROL_MASK) && !(mask & GDK_SHIFT_MASK)) + nNewDropAction = css::datatransfer::dnd::DNDConstants::ACTION_COPY; + else if ((mask & GDK_SHIFT_MASK) && (mask & GDK_CONTROL_MASK) ) + nNewDropAction = css::datatransfer::dnd::DNDConstants::ACTION_LINK; + nNewDropAction &= nSourceActions; + + GdkDragAction eAction; + if (!(mask & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) && !nNewDropAction) + eAction = getPreferredDragAction(nSourceActions); + else + eAction = getPreferredDragAction(nNewDropAction); + gdk_drag_status(context, eAction, time); aEvent.Context = pContext; aEvent.LocationX = x; |