[Libreoffice-commits] core.git: vcl/unx

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Tue Aug 20 16:24:06 UTC 2019


 vcl/unx/gtk3/gtk3gtkframe.cxx |   25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

New commits:
commit 98f41c22b85e76fb8354a4b9df57f4211824e95e
Author:     Jan-Marek Glogowski <jan-marek.glogowski at extern.cib.de>
AuthorDate: Mon Aug 19 17:45:14 2019 +0000
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Tue Aug 20 18:23:11 2019 +0200

    Gtk3 defer LO dragExit handling to an idle
    
    LO expects to handle either a drop or an exit event. Quoting the
    Gtk+ docs: "Likewise, the “drag-leave” signal is also emitted
    before the ::drag-drop signal, for instance to allow cleaning up
    of a preview item created in the “drag-motion” signal handler."
    
    Since we don't know if there will be a drop-event following the
    leave event, we have to defer the "fire_draExit" to an idle, which
    will be removed by the drop event, before it can be processed.
    
    Fixes D'n'D between two Writer windows. For whatever reason it
    works correct in Calc, which probably needs further investigation.
    
    Regression from commit c70b86588fe5 ("Gtk3 inform LO of drag
    leave").
    
    Change-Id: Ia59dcc8b20efd442ac5efc895602e5cc432cc379
    Reviewed-on: https://gerrit.libreoffice.org/77753
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index 53d492f4b8aa..899b2161eefe 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -3438,6 +3438,13 @@ gboolean GtkSalFrame::signalDragDrop(GtkWidget* pWidget, GdkDragContext* context
 
 gboolean GtkDropTarget::signalDragDrop(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, guint time)
 {
+    // remove the deferred dragExit, as we'll do a drop
+#ifndef NDEBUG
+    gboolean res =
+#endif
+        g_idle_remove_by_data(this);
+    assert(res);
+
     css::datatransfer::dnd::DropTargetDropEvent aEvent;
     aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(this);
     aEvent.Context = new GtkDropTargetDropContext(context, time);
@@ -3606,14 +3613,24 @@ void GtkSalFrame::signalDragLeave(GtkWidget *pWidget, GdkDragContext *context, g
     pThis->m_pDropTarget->signalDragLeave(pWidget, context, time);
 }
 
+static gboolean lcl_deferred_dragExit(gpointer user_data)
+{
+    GtkDropTarget* pThis = static_cast<GtkDropTarget*>(user_data);
+    css::datatransfer::dnd::DropTargetEvent aEvent;
+    aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(pThis);
+    pThis->fire_dragExit(aEvent);
+    return FALSE;
+}
+
 void GtkDropTarget::signalDragLeave(GtkWidget* pWidget, GdkDragContext* /*context*/, guint /*time*/)
 {
     m_bInDrag = false;
     gtk_drag_unhighlight(pWidget);
-
-    css::datatransfer::dnd::DropTargetEvent aEvent;
-    aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(this);
-    fire_dragExit(aEvent);
+    // defer fire_dragExit, since gtk also sends a drag-leave before the drop, while
+    // LO expect to either handle the drop or the exit... at least in Writer.
+    // but since we don't know there will be a drop following the leave, defer the
+    // exit handling to an idle.
+    g_idle_add(lcl_deferred_dragExit, this);
 }
 
 void GtkSalFrame::signalDestroy( GtkWidget* pObj, gpointer frame )


More information about the Libreoffice-commits mailing list