summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2017-07-27 09:08:02 +0100
committerMichael Stahl <mstahl@redhat.com>2017-07-27 22:44:55 +0200
commitab273651477d76890fc4268277b52893d89edc0b (patch)
tree160dfd2847e106b412ea37e0b8141e4524e11602
parent8eb05127e8ffcbe4a6bd6eb10b073d015cea34aa (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.cxx28
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;