forked from AuroraMiddleware/gtk
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:
parent
e0e114fddb
commit
c27c4e2048
13
gtk/gtkdnd.c
13
gtk/gtkdnd.c
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user