From cdedf7f617e76b024c384e6d842487e6d8f67f46 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 20 Jul 2015 16:55:51 -0400 Subject: [PATCH] patches to fix notebook tab tearoff on DnD. See also https://bugzilla.gnome.org/show_bug.cgi?id=752638 for updates on integration into GTK+ 2 and GTK+ 3 --- patches/GdkQuartzWindow.patch | 44 ++++++++++++++++++++++++++++ patches/gtkdnd-quartz.patch | 55 +++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 patches/GdkQuartzWindow.patch create mode 100644 patches/gtkdnd-quartz.patch diff --git a/patches/GdkQuartzWindow.patch b/patches/GdkQuartzWindow.patch new file mode 100644 index 0000000000..217c010ffb --- /dev/null +++ b/patches/GdkQuartzWindow.patch @@ -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 index 0000000000..07723ad533 --- /dev/null +++ b/patches/gtkdnd-quartz.patch @@ -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 ();