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.
This commit is contained in:
Matthias Clasen 2016-04-26 20:35:25 -04:00
parent e0e114fddb
commit c27c4e2048

View File

@ -2011,6 +2011,13 @@ gtk_drag_begin (GtkWidget *widget,
actions, button, event, -1, -1);
}
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,
@ -2041,6 +2048,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)
@ -2715,11 +2724,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);
}