From 81340da8b66403a64fb85f3a9d465033bcb6bb01 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 9 May 2020 16:05:08 -0400 Subject: [PATCH] nativedialog: Do not ref the transient_for parent gtk_window_set_transient_for does not ref its parent either. This is important because a child widget of the parent might be the one calling this function. This was showing up as widget-factory not existing on close after opening the file chooser. --- gtk/gtknativedialog.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/gtk/gtknativedialog.c b/gtk/gtknativedialog.c index c97c6c0697..1a060be27a 100644 --- a/gtk/gtknativedialog.c +++ b/gtk/gtknativedialog.c @@ -168,12 +168,21 @@ gtk_native_dialog_get_property (GObject *object, } } +static void parent_destroyed (GtkWidget *parent, + GtkNativeDialog *self); + static void gtk_native_dialog_dispose (GObject *object) { GtkNativeDialog *self = GTK_NATIVE_DIALOG (object); GtkNativeDialogPrivate *priv = gtk_native_dialog_get_instance_private (self); + if (priv->transient_for) + { + g_signal_handlers_disconnect_by_func (priv->transient_for, parent_destroyed, self); + priv->transient_for = NULL; + } + if (priv->visible) gtk_native_dialog_hide (self); @@ -486,6 +495,15 @@ gtk_native_dialog_get_title (GtkNativeDialog *self) return priv->title; } +static void +parent_destroyed (GtkWidget *parent, + GtkNativeDialog *self) +{ + GtkNativeDialogPrivate *priv = gtk_native_dialog_get_instance_private (self); + + priv->transient_for = NULL; +} + /** * gtk_native_dialog_set_transient_for: * @self: a #GtkNativeDialog @@ -501,14 +519,24 @@ gtk_native_dialog_get_title (GtkNativeDialog *self) */ void gtk_native_dialog_set_transient_for (GtkNativeDialog *self, - GtkWindow *parent) + GtkWindow *parent) { GtkNativeDialogPrivate *priv = gtk_native_dialog_get_instance_private (self); g_return_if_fail (GTK_IS_NATIVE_DIALOG (self)); - if (g_set_object (&priv->transient_for, parent)) - g_object_notify_by_pspec (G_OBJECT (self), native_props[PROP_TRANSIENT_FOR]); + if (parent == priv->transient_for) + return; + + if (priv->transient_for) + g_signal_handlers_disconnect_by_func (priv->transient_for, parent_destroyed, self); + + priv->transient_for = parent; + + if (parent) + g_signal_connect (parent, "destroy", G_CALLBACK (parent_destroyed), self); + + g_object_notify_by_pspec (G_OBJECT (self), native_props[PROP_TRANSIENT_FOR]); } /**