summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2016-05-30 10:57:10 +0100
committerCaolán McNamara <caolanm@redhat.com>2016-05-30 11:16:51 +0100
commit73f84ab139cb1d2564f9292fba08d69a0ab822c1 (patch)
treeb971423c147277b5129ce0e6343d07ca4c6ed275
parentcd34f76d4ef7371892be4b8970a45d2d3e81e9db (diff)
Resolves: tdf#100097 dbaccess self-dnd depends on getting its own transferable
on drop that it set on drag. It does some uno tunnel foo to drag the data it needs back out of it in some grotesque fashion. So we have to follow the same style of hackery as under MacOSX to detect on drop that there is an active drag started by ourself and so use that active drag's transferable as the source transferable for the drop, rather that use the intermediate universal GtkDnDTransferable. Change-Id: I3c3a94416db908603bde8f15dc5b1c9d726b8dbd
-rw-r--r--vcl/inc/unx/gtk/gtkinst.hxx5
-rw-r--r--vcl/osx/DragSource.cxx4
-rw-r--r--vcl/unx/gtk3/gtk3gtkframe.cxx35
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx6
4 files changed, 41 insertions, 9 deletions
diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index 6f1f9999bc9b..5218eb4686f3 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -171,6 +171,11 @@ public:
void dragDelete();
void dragEnd(GdkDragContext* context);
void dragDataGet(GtkSelectionData *data, guint info);
+
+ // For LibreOffice internal D&D we provide the Transferable without Gtk
+ // intermediaries as a shortcut, see tdf#100097 for how dbaccess depends on this
+ static GtkDragSource* g_ActiveDragSource;
+ css::uno::Reference<css::datatransfer::XTransferable> GetTransferrable() const { return m_xTrans; }
};
#endif
diff --git a/vcl/osx/DragSource.cxx b/vcl/osx/DragSource.cxx
index c72b4bcaa2d0..d794d1fb808d 100644
--- a/vcl/osx/DragSource.cxx
+++ b/vcl/osx/DragSource.cxx
@@ -47,8 +47,8 @@ using namespace com::sun::star::awt;
using namespace com::sun::star::lang;
using namespace comphelper;
-// For OOo internal D&D we provide the Transferable without NSDragPboard
-// interference as a shortcut
+// For LibreOffice internal D&D we provide the Transferable without NSDragPboard
+// interference as a shortcut, see tdf#100097 for how dbaccess depends on this
uno::Reference<XTransferable> DragSource::g_XTransferable;
NSView* DragSource::g_DragSourceView = nil;
bool DragSource::g_DropSuccessSet = false;
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index bac7584b46ec..ee02b03046d1 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -3296,6 +3296,10 @@ public:
}
};
+// For LibreOffice internal D&D we provide the Transferable without Gtk
+// intermediaries as a shortcut, see tdf#100097 for how dbaccess depends on this
+GtkDragSource* GtkDragSource::g_ActiveDragSource;
+
gboolean GtkSalFrame::signalDragDrop(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, guint time, gpointer frame)
{
GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
@@ -3310,7 +3314,13 @@ gboolean GtkSalFrame::signalDragDrop(GtkWidget* pWidget, GdkDragContext* context
aEvent.LocationY = y;
aEvent.DropAction = GdkToVcl(gdk_drag_context_get_selected_action(context));
aEvent.SourceActions = GdkToVcl(gdk_drag_context_get_actions(context));
- css::uno::Reference<css::datatransfer::XTransferable> xTransferable(new GtkDnDTransferable(context, time, pWidget, pThis));
+ css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
+ // For LibreOffice internal D&D we provide the Transferable without Gtk
+ // intermediaries as a shortcut, see tdf#100097 for how dbaccess depends on this
+ if (GtkDragSource::g_ActiveDragSource)
+ xTransferable = GtkDragSource::g_ActiveDragSource->GetTransferrable();
+ else
+ xTransferable = new GtkDnDTransferable(context, time, pWidget, pThis);
aEvent.Transferable = xTransferable;
pThis->m_pDropTarget->fire_drop(aEvent);
@@ -3366,7 +3376,7 @@ void GtkSalFrame::signalDragDropReceived(GtkWidget* /*pWidget*/, GdkDragContext
pThis->m_pFormatConversionRequest->LoopEnd(gtk_selection_data_copy(data));
}
-gboolean GtkSalFrame::signalDragMotion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer frame)
+gboolean GtkSalFrame::signalDragMotion(GtkWidget *pWidget, GdkDragContext *context, gint x, gint y, guint time, gpointer frame)
{
GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
@@ -3374,7 +3384,7 @@ gboolean GtkSalFrame::signalDragMotion(GtkWidget *widget, GdkDragContext *contex
return false;
if (!pThis->m_bInDrag)
- gtk_drag_highlight(widget);
+ gtk_drag_highlight(pWidget);
css::datatransfer::dnd::DropTargetDragEnterEvent aEvent;
aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(pThis->m_pDropTarget);
@@ -3391,8 +3401,14 @@ gboolean GtkSalFrame::signalDragMotion(GtkWidget *widget, GdkDragContext *contex
if (!pThis->m_bInDrag)
{
- css::uno::Reference<css::datatransfer::XTransferable> xTrans(new GtkDnDTransferable(context, time, widget, pThis));
- css::uno::Sequence<css::datatransfer::DataFlavor> aFormats = xTrans->getTransferDataFlavors();
+ css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
+ // For LibreOffice internal D&D we provide the Transferable without Gtk
+ // intermediaries as a shortcut, see tdf#100097 for how dbaccess depends on this
+ if (GtkDragSource::g_ActiveDragSource)
+ xTransferable = GtkDragSource::g_ActiveDragSource->GetTransferrable();
+ else
+ xTransferable = new GtkDnDTransferable(context, time, pWidget, pThis);
+ css::uno::Sequence<css::datatransfer::DataFlavor> aFormats = xTransferable->getTransferDataFlavors();
aEvent.SupportedDataFlavors = aFormats;
pThis->m_pDropTarget->fire_dragEnter(aEvent);
pThis->m_bInDrag = true;
@@ -3405,13 +3421,13 @@ gboolean GtkSalFrame::signalDragMotion(GtkWidget *widget, GdkDragContext *contex
return true;
}
-void GtkSalFrame::signalDragLeave(GtkWidget *widget, GdkDragContext * /*context*/, guint /*time*/, gpointer frame)
+void GtkSalFrame::signalDragLeave(GtkWidget *pWidget, GdkDragContext * /*context*/, guint /*time*/, gpointer frame)
{
GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
if (!pThis->m_pDropTarget)
return;
pThis->m_bInDrag = false;
- gtk_drag_unhighlight(widget);
+ gtk_drag_unhighlight(pWidget);
#if 0
css::datatransfer::dnd::DropTargetEvent aEvent;
@@ -4050,6 +4066,10 @@ void GtkDragSource::startDrag(const datatransfer::dnd::DragGestureEvent& rEvent,
nDragButton = 2;
}
+ // For LibreOffice internal D&D we provide the Transferable without Gtk
+ // intermediaries as a shortcut, see tdf#100097 for how dbaccess depends on this
+ g_ActiveDragSource = this;
+
m_pFrame->startDrag(nDragButton, rEvent.DragOriginX, rEvent.DragOriginY,
VclToGdk(sourceActions), pTargetList);
gtk_target_list_unref(pTargetList);
@@ -4136,6 +4156,7 @@ void GtkDragSource::dragEnd(GdkDragContext* context)
aEv.DropAction = GdkToVcl(gdk_drag_context_get_selected_action(context));
aEv.DropSuccess = gdk_drag_drop_succeeded(context);
m_xListener->dragDropEnd(aEv);
+ g_ActiveDragSource = nullptr;
}
void GtkSalFrame::signalDragEnd(GtkWidget* /*widget*/, GdkDragContext* context, gpointer frame)
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 768f4b15e2ba..ed64ded2ece5 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -824,6 +824,12 @@ GtkDragSource::~GtkDragSource()
{
if (m_pFrame)
m_pFrame->deregisterDragSource(this);
+
+ if (GtkDragSource::g_ActiveDragSource == this)
+ {
+ SAL_WARN( "vcl.gtk", "dragEnd should have been called on GtkDragSource before dtor");
+ GtkDragSource::g_ActiveDragSource = nullptr;
+ }
}
void GtkDragSource::deinitialize()