From 353281d9d07ac49082cf2de19d7de33d5eb2e02d Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Wed, 12 Oct 2016 13:33:39 +0100 Subject: [PATCH] applicationwindow: fix leak of help_overlay > Due to Gtk+ keeping a reference to the window internally, > gtk_window_new() does not return a reference to the caller. > To delete a GtkWindow, call gtk_widget_destroy(). Caller(s) aren't expecting a need to delete help_overlay themselves once they've installed it. (E.g. see gtk_application_window_added()). I didn't notice any direct precedents, but there's a parallel in the current implementation of gtk_container_destroy() which uses gtk_widget_destroy() on any added widget. This avoids leaking 100s of kB per window, when I tested nautilus. https://bugzilla.gnome.org/show_bug.cgi?id=772859 --- gtk/gtkapplicationwindow.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/gtk/gtkapplicationwindow.c b/gtk/gtkapplicationwindow.c index 2128f983c1..3e1e9692b0 100644 --- a/gtk/gtkapplicationwindow.c +++ b/gtk/gtkapplicationwindow.c @@ -794,7 +794,12 @@ gtk_application_window_dispose (GObject *object) g_clear_object (&window->priv->app_menu_section); g_clear_object (&window->priv->menubar_section); - g_clear_object (&window->priv->help_overlay); + + if (window->priv->help_overlay) + { + gtk_widget_destroy (GTK_WIDGET (window->priv->help_overlay)); + g_clear_object (&window->priv->help_overlay); + } G_OBJECT_CLASS (gtk_application_window_parent_class)->dispose (object); @@ -986,6 +991,8 @@ show_help_overlay (GSimpleAction *action, * sets up an action with the name win.show-help-overlay to present * it. * + * @window takes resposibility for destroying @help_overlay. + * * Since: 3.20 */ void @@ -996,8 +1003,7 @@ gtk_application_window_set_help_overlay (GtkApplicationWindow *window, g_return_if_fail (help_overlay == NULL || GTK_IS_SHORTCUTS_WINDOW (help_overlay)); if (window->priv->help_overlay) - g_signal_handlers_disconnect_by_func (window->priv->help_overlay, - G_CALLBACK (gtk_widget_hide_on_delete), NULL); + gtk_widget_destroy (GTK_WIDGET (window->priv->help_overlay)); g_set_object (&window->priv->help_overlay, help_overlay); if (!window->priv->help_overlay)