patches to fix notebook tab tearoff on DnD.
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 20 Jul 2015 20:55:51 +0000 (16:55 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 20 Jul 2015 20:56:15 +0000 (16:56 -0400)
See also https://bugzilla.gnome.org/show_bug.cgi?id=752638 for updates
on integration into GTK+ 2 and GTK+ 3

patches/GdkQuartzWindow.patch [new file with mode: 0644]
patches/gtkdnd-quartz.patch [new file with mode: 0644]

diff --git a/patches/GdkQuartzWindow.patch b/patches/GdkQuartzWindow.patch
new file mode 100644 (file)
index 0000000..217c010
--- /dev/null
@@ -0,0 +1,44 @@
+--- old/gtk+-2.24.23/gdk/quartz/GdkQuartzWindow.c      2013-10-16 11:29:55.000000000 -0400
++++ new/gtk+-2.24.23/gdk/quartz/GdkQuartzWindow.c      2015-07-20 15:05:40.000000000 -0400
+@@ -625,6 +625,41 @@
+   event.dnd.send_event = FALSE;
+   event.dnd.context = _gdk_quartz_drag_source_context;
++  /* Check to see if the coordinates are inside a known GdkWindow */
++
++  GdkScreen* screen = gdk_window_get_screen (event.dnd.window);
++
++  if (screen) 
++    {
++       GList* windows, *list;
++       gint gx, gy;
++       
++       event.dnd.context->dest_window = NULL;
++
++       windows = gdk_screen_get_toplevel_windows (screen);
++       _gdk_quartz_window_nspoint_to_gdk_xy (aPoint, &gx, &gy);
++       
++       for (list = windows; list; list = list->next) 
++         {
++            GdkWindow* win = (GdkWindow*) list->data;
++            gint wx, wy;
++            gint ww, wh;
++            
++            gdk_window_get_root_origin (win, &wx, &wy);
++            ww = gdk_window_get_width (win);
++            wh = gdk_window_get_height (win);
++            
++            if (gx > wx && 
++                gy > wy &&
++                gx <= wx + ww && 
++                gy <= wy + wh) 
++              {
++                 /* found a toplevel GdkWindow at the drop position */
++                 event.dnd.context->dest_window = win;
++              }
++         }
++    }
++
+   (*_gdk_event_func) (&event, _gdk_event_data);
+   g_object_unref (event.dnd.window);
diff --git a/patches/gtkdnd-quartz.patch b/patches/gtkdnd-quartz.patch
new file mode 100644 (file)
index 0000000..07723ad
--- /dev/null
@@ -0,0 +1,55 @@
+--- old/gtk+-2.24.23/gtk/gtkdnd-quartz.c       2013-10-16 11:29:55.000000000 -0400
++++ new/gtk+-2.24.23/gtk/gtkdnd-quartz.c       2015-07-20 14:53:33.000000000 -0400
+@@ -1928,16 +1928,29 @@
+ static gboolean
+ drag_drop_finished_idle_cb (gpointer data)
+ {
+-  gtk_drag_source_info_destroy (data);
++  GtkDragSourceInfo* info = (GtkDragSourceInfo*) data;
++  if (info->success) 
++    {
++       gtk_drag_source_info_destroy (data);
++    }
+   return FALSE;
+ }
+ static void
+-gtk_drag_drop_finished (GtkDragSourceInfo *info)
++gtk_drag_drop_finished (GtkDragSourceInfo *info, GtkDragResult result)
+ {
+-  if (info->success && info->delete)
+-    g_signal_emit_by_name (info->source_widget, "drag-data-delete",
+-                           info->context);
++        gboolean success = (result == GTK_DRAG_RESULT_SUCCESS);
++
++        if (!success) {
++                g_signal_emit_by_name (info->source_widget, "drag-failed",
++                                       info->context, GTK_DRAG_RESULT_NO_TARGET, &success);
++        }
++                
++        if (success && info->delete) {
++                g_signal_emit_by_name (info->source_widget, "drag-data-delete",
++                                       info->context);
++        }
++
+   /* Workaround for the fact that the NS API blocks until the drag is
+    * over. This way the context is still valid when returning from
+@@ -1963,6 +1976,7 @@
+ {
+   GtkDragSourceInfo *info;
+   GdkDragContext *context;
++  GtkDragResult result;
+   g_return_if_fail (widget != NULL);
+   g_return_if_fail (event != NULL);
+@@ -1975,7 +1989,8 @@
+   switch (event->type)
+     {
+     case GDK_DROP_FINISHED:
+-      gtk_drag_drop_finished (info);
++      result = (gdk_drag_context_get_dest_window (context) != NULL) ? GTK_DRAG_RESULT_SUCCESS : GTK_DRAG_RESULT_NO_TARGET;
++      gtk_drag_drop_finished (info, result);
+       break;
+     default:
+       g_assert_not_reached ();