This patch is applied upstream to fix http://bugzilla.gnome.org/show_bug.cgi?id=122688 As this regresses mozilla products drag-and-drop (bug 162362) we are reverse applying it as what it fixed is a corner case while mozilla case is a big problem. The real problem is inside mozilla code, see http://bugzilla.gnome.org/show_bug.cgi?id=394525 but we can't fix this for binary thunderbird/firefox/seamonkey packages --- /branches/gtk-2-10/gtk/gtkdnd.c 2006/11/05 08:55:47 16711 +++ branches/gtk-2-10/gtk/gtkdnd.c 2006/11/06 17:16:37 16712 @@ -285,6 +285,9 @@ static gboolean gtk_drag_grab_broken_event_cb (GtkWidget *widget, GdkEventGrabBroken *event, gpointer data); +static void gtk_drag_grab_notify_cb (GtkWidget *widget, + gboolean was_grabbed, + gpointer data); static gboolean gtk_drag_button_release_cb (GtkWidget *widget, GdkEventButton *event, gpointer data); @@ -2331,6 +2334,8 @@ g_signal_connect (info->ipc_widget, "grab_broken_event", G_CALLBACK (gtk_drag_grab_broken_event_cb), info); + g_signal_connect (info->ipc_widget, "grab_notify", + G_CALLBACK (gtk_drag_grab_notify_cb), info); g_signal_connect (info->ipc_widget, "button_release_event", G_CALLBACK (gtk_drag_button_release_cb), info); g_signal_connect (info->ipc_widget, "motion_notify_event", @@ -3762,6 +3767,9 @@ gtk_drag_grab_broken_event_cb, info); g_signal_handlers_disconnect_by_func (info->ipc_widget, + gtk_drag_grab_notify_cb, + info); + g_signal_handlers_disconnect_by_func (info->ipc_widget, gtk_drag_button_release_cb, info); g_signal_handlers_disconnect_by_func (info->ipc_widget, @@ -3926,6 +3934,9 @@ gtk_drag_grab_broken_event_cb, info); g_signal_handlers_disconnect_by_func (info->ipc_widget, + gtk_drag_grab_notify_cb, + info); + g_signal_handlers_disconnect_by_func (info->ipc_widget, gtk_drag_button_release_cb, info); g_signal_handlers_disconnect_by_func (info->ipc_widget, @@ -4117,6 +4128,24 @@ return TRUE; } +static void +gtk_drag_grab_notify_cb (GtkWidget *widget, + gboolean was_grabbed, + gpointer data) +{ + GtkDragSourceInfo *info = (GtkDragSourceInfo *)data; + + if (!was_grabbed) + { + /* We have to block callbacks to avoid recursion here, because + gtk_drag_cancel calls gtk_grab_remove (via gtk_drag_end) */ + g_signal_handlers_block_by_func (widget, gtk_drag_grab_notify_cb, data); + gtk_drag_cancel (info, gtk_get_current_event_time ()); + g_signal_handlers_unblock_by_func (widget, gtk_drag_grab_notify_cb, data); + } +} + + /************************************************************* * gtk_drag_button_release_cb: * "button_release_event" callback during drag.