[gimp/gimp-2-10] Issue #1924: Tool options mysteriously lock up due to DND/quartz issues.



commit 6b1ff0dd96765405560ddfa0ded8a126bf321784
Author: Jehan <jehan girinstud io>
Date:   Fri Oct 19 19:21:26 2018 +0200

    Issue #1924: Tool options mysteriously lock up due to DND/quartz issues.
    
    On macOS, the "drag-end" signal does not seem to be emitted in some
    cases, which leaves dockables in an unsensitive state. Rather than
    trying to fix GTK+2 which is half-maintained nowadays anyway, let's drop
    the unsensitivity. As a comment notes, this was anyway only a visual
    cue. Dragging dockables in GIMP 2.10 already shows a lot of other visual
    cues, so this is redundant.
    In case of drop failure, we also had to cleanup the icon widget and
    detach the dockable. This can be handled by the "drag-failed" (which
    hopefully work better on macOS).
    
    As an additional improvement, I raise the newly created dockable window,
    since this is the most likely behavior when you just detached a dock
    (and I realize it usually appeared behind other GIMP windows, at least
    on GNOME).
    
    Note: this is a gimp-2-10 only fix as master relies on GtkNotebook DnD
    code which (hopefully, as I haven't tested) doesn't have this issue. The
    detached window behind other windows issue doesn't exist on master, at
    the very least.

 app/widgets/gimpdockbook.c | 69 +++++++++++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 26 deletions(-)
---
diff --git a/app/widgets/gimpdockbook.c b/app/widgets/gimpdockbook.c
index 2e4a2eaa58..0a100e9d3b 100644
--- a/app/widgets/gimpdockbook.c
+++ b/app/widgets/gimpdockbook.c
@@ -143,8 +143,9 @@ static void         gimp_dockbook_tab_drag_source_setup       (GtkWidget      *w
 static void         gimp_dockbook_tab_drag_begin              (GtkWidget      *widget,
                                                                GdkDragContext *context,
                                                                GimpDockable   *dockable);
-static void         gimp_dockbook_tab_drag_end                (GtkWidget      *widget,
+static gboolean     gimp_dockbook_tab_drag_failed             (GtkWidget      *widget,
                                                                GdkDragContext *context,
+                                                               GtkDragResult   result,
                                                                GimpDockable   *dockable);
 static void         gimp_dockbook_tab_drag_leave              (GtkWidget      *widget,
                                                                GdkDragContext *context,
@@ -1031,6 +1032,10 @@ gimp_dockbook_add_from_dialog_factory (GimpDockbook *dockbook,
   if (dockable && ! gimp_dockable_get_dockbook (GIMP_DOCKABLE (dockable)))
     gimp_dockbook_add (dockbook, GIMP_DOCKABLE (dockable), position);
 
+  if (dockable)
+    gimp_dockable_set_drag_pos (GIMP_DOCKABLE (dockable),
+                                GIMP_DOCKABLE_DRAG_OFFSET,
+                                GIMP_DOCKABLE_DRAG_OFFSET);
   return dockable;
 }
 
@@ -1177,15 +1182,15 @@ gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
   g_signal_connect_object (tab_widget, "drag-begin",
                            G_CALLBACK (gimp_dockbook_tab_drag_begin),
                            dockable, 0);
-  g_signal_connect_object (tab_widget, "drag-end",
-                           G_CALLBACK (gimp_dockbook_tab_drag_end),
+  g_signal_connect_object (tab_widget, "drag-failed",
+                           G_CALLBACK (gimp_dockbook_tab_drag_failed),
                            dockable, 0);
 
   g_signal_connect_object (dockable, "drag-begin",
                            G_CALLBACK (gimp_dockbook_tab_drag_begin),
                            dockable, 0);
-  g_signal_connect_object (dockable, "drag-end",
-                           G_CALLBACK (gimp_dockbook_tab_drag_end),
+  g_signal_connect_object (dockable, "drag-failed",
+                           G_CALLBACK (gimp_dockbook_tab_drag_failed),
                            dockable, 0);
 
   gtk_drag_dest_set (tab_widget,
@@ -1395,37 +1400,49 @@ gimp_dockbook_tab_drag_begin (GtkWidget      *widget,
 
   gimp_dockable_get_drag_pos (dockable, &drag_x, &drag_y);
   gtk_drag_set_icon_widget (context, window, drag_x, drag_y);
-
-  /*
-   * Set the source dockable insensitive to give a visual clue that
-   * it's the dockable that's being dragged around
-   */
-  gtk_widget_set_sensitive (GTK_WIDGET (dockable), FALSE);
 }
 
-static void
-gimp_dockbook_tab_drag_end (GtkWidget      *widget,
-                            GdkDragContext *context,
-                            GimpDockable   *dockable)
+static gboolean
+gimp_dockbook_tab_drag_failed (GtkWidget      *widget,
+                               GdkDragContext *context,
+                               GtkDragResult   result,
+                               GimpDockable   *dockable)
 {
+  /* XXX The proper way is to handle "drag-end" signal instead.
+   * Unfortunately this signal seems to be broken in various cases on
+   * macOS/GTK+2 (see #1924). As a consequence, we made sure we don't
+   * have anything to clean unconditionally (for instance we used to set
+   * the dockable unsensitive, which anyway was only a visual clue and
+   * is not really useful). Only thing left to handle is the dockable
+   * detachment when dropping in a non-droppable area.
+   */
   GtkWidget *drag_widget;
+  GtkWidget *window;
+
+  if (result == GTK_DRAG_RESULT_SUCCESS)
+    {
+      /* I don't think this should happen, considering we are in the
+       * "drag-failed" handler, but let's be complete as it is a
+       * possible GtkDragResult value. Just in case!
+       */
+      return FALSE;
+    }
 
   drag_widget = g_object_get_data (G_OBJECT (dockable),
                                    "gimp-dock-drag-widget");
 
-  /*  finding the drag_widget means the drop was not successful, so
-   *  pop up a new dock and move the dockable there
+  /* The drag_widget should be present if the drop was not successful,
+   * in which case, we pop up a new dock and move the dockable there.
    */
-  if (drag_widget)
-    {
-      g_object_set_data (G_OBJECT (dockable), "gimp-dock-drag-widget", NULL);
-      gimp_dockable_detach (dockable);
-    }
+  g_return_val_if_fail (drag_widget, FALSE);
+
+  g_object_set_data (G_OBJECT (dockable), "gimp-dock-drag-widget", NULL);
+  gimp_dockable_detach (dockable);
 
-  gimp_dockable_set_drag_pos (dockable,
-                              GIMP_DOCKABLE_DRAG_OFFSET,
-                              GIMP_DOCKABLE_DRAG_OFFSET);
-  gtk_widget_set_sensitive (GTK_WIDGET (dockable), TRUE);
+  window = gtk_widget_get_toplevel (GTK_WIDGET (dockable));
+  gtk_window_present (GTK_WINDOW (window));
+
+  return TRUE;
 }
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]