summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2016-04-26 20:35:25 -0400
committerMatthias Clasen <mclasen@redhat.com>2016-05-05 15:03:59 -0400
commit7054b0ccff7c977ad51c1f4ae13848b4704c246e (patch)
tree1e83f98125e2bf26346a06091ac1f1eb0aa3183b
parentea0d3d2a9511d9329f10f472947bd134988370b1 (diff)
downloadgtk+-7054b0ccff7c977ad51c1f4ae13848b4704c246e.tar.gz
dnd: Fix lifecycle issues with widgets as drag icons
The documentation clearly says that the widget is not destroyed, but we were in fact failing to keep it alive, since it was still a child or the icon_window when we destroy that. Fix this by reparenting the icon_widget out before. Also, deal with the possibility that the application might destroy the widget halfway through, for whatever reason.
-rw-r--r--gtk/gtkdnd.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index 48be48c355..a055c308d2 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -2501,6 +2501,13 @@ gtk_drag_begin (GtkWidget *widget,
}
static void
+icon_widget_destroyed (GtkWidget *widget,
+ GtkDragSourceInfo *info)
+{
+ g_clear_object (&info->icon_widget);
+}
+
+static void
gtk_drag_set_icon_widget_internal (GdkDragContext *context,
GtkWidget *widget,
gint hot_x,
@@ -2530,6 +2537,8 @@ gtk_drag_set_icon_widget_internal (GdkDragContext *context,
if (!widget)
goto out;
+ g_signal_connect (widget, "destroy", G_CALLBACK (icon_widget_destroyed), info);
+
gdk_drag_context_set_hotspot (context, hot_x, hot_y);
if (!info->icon_window)
@@ -3204,11 +3213,15 @@ gtk_drag_remove_icon (GtkDragSourceInfo *info)
widget = info->icon_widget;
info->icon_widget = NULL;
+ g_signal_handlers_disconnect_by_func (widget, icon_widget_destroyed, info);
+
gtk_widget_hide (widget);
gtk_widget_set_opacity (widget, 1.0);
if (info->destroy_icon)
gtk_widget_destroy (widget);
+ else
+ gtk_container_remove (GTK_CONTAINER (info->icon_window), widget);
g_object_unref (widget);
}