[Libreoffice-commits] core.git: Branch 'libreoffice-5-2' - vcl/inc vcl/osx vcl/unx

Caolán McNamara caolanm at redhat.com
Mon May 30 10:20:40 UTC 2016


 vcl/inc/unx/gtk/gtkinst.hxx   |    5 +++++
 vcl/osx/DragSource.cxx        |    4 ++--
 vcl/unx/gtk3/gtk3gtkframe.cxx |   35 ++++++++++++++++++++++++++++-------
 vcl/unx/gtk3/gtk3gtkinst.cxx  |    6 ++++++
 4 files changed, 41 insertions(+), 9 deletions(-)

New commits:
commit 6f41a9b06219c2d8e176f84a5ae4b80b22dc9ce5
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon May 30 10:57:10 2016 +0100

    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
    (cherry picked from commit 73f84ab139cb1d2564f9292fba08d69a0ab822c1)

diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index 6f1f999..5218eb4 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 c72b4bc..d794d1f 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 0bb9bf7..2c04616 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;
@@ -4059,6 +4075,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);
@@ -4145,6 +4165,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 768f4b1..ed64ded 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()


More information about the Libreoffice-commits mailing list