From c56e90ed699d155a5653d1b703ad4e41bcf4aa7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Fernandes?= Date: Tue, 26 Oct 2021 12:20:57 +0100 Subject: pathbar: Avoid leaking stack pages The templates submenu in the current location popover is recreated every time the menu model is updated, but the old widgetry is never destroyed. This results in a memory leak and many warnings in the terminal output. I couldn't find the root cause, after many investigations. However, I've found that unsetting the model actually removes the old widgetry. Let's do that as a workaround. Fixes https://gitlab.gnome.org/GNOME/nautilus/-/issues/1705 --- src/nautilus-pathbar.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/nautilus-pathbar.c b/src/nautilus-pathbar.c index 68cd38639..622686b47 100644 --- a/src/nautilus-pathbar.c +++ b/src/nautilus-pathbar.c @@ -236,8 +236,7 @@ nautilus_path_bar_init (NautilusPathBar *self) self->current_view_menu = g_object_ref_sink (G_MENU (gtk_builder_get_object (builder, "background-menu"))); self->extensions_section = g_object_ref (G_MENU (gtk_builder_get_object (builder, "background-extensions-section"))); self->templates_submenu = g_object_ref (G_MENU (gtk_builder_get_object (builder, "templates-submenu"))); - self->current_view_menu_popover = g_object_ref_sink (GTK_POPOVER (gtk_popover_new_from_model (NULL, - G_MENU_MODEL (self->current_view_menu)))); + self->current_view_menu_popover = g_object_ref_sink (GTK_POPOVER (gtk_popover_new (NULL))); g_object_unref (builder); @@ -946,6 +945,16 @@ nautilus_path_bar_set_templates_menu (NautilusPathBar *self, { g_return_if_fail (NAUTILUS_IS_PATH_BAR (self)); + if (!gtk_widget_is_visible (GTK_WIDGET (self->current_view_menu_popover))) + { + /* Workaround to avoid leaking duplicated GtkStack pages each time the + * templates menu is set. Unbinding the model is the only way to clear + * all children. For that reason, we need to rebind the popover before + * it is shown again. + * See https://gitlab.gnome.org/GNOME/nautilus/-/issues/1705 */ + gtk_popover_bind_model (self->current_view_menu_popover, NULL, NULL); + } + nautilus_gmenu_set_from_model (self->templates_submenu, menu); } @@ -1042,6 +1051,14 @@ button_clicked_cb (GtkButton *button, { if (g_file_equal (button_data->path, self->current_path)) { + /* Workaround to avoid leaking duplicated GtkStack pages each time the + * templates menu is set. Unbinding the model is the only way to clear + * all children. For that reason, we need to rebind the popover before + * it is shown again. + * See https://gitlab.gnome.org/GNOME/nautilus/-/issues/1705 */ + gtk_popover_bind_model (self->current_view_menu_popover, + G_MENU_MODEL (self->current_view_menu), + NULL); gtk_popover_popup (self->current_view_menu_popover); } else @@ -1169,6 +1186,14 @@ on_multi_press_gesture_pressed (GtkGestureMultiPress *gesture, { if (g_file_equal (button_data->path, self->current_path)) { + /* Workaround to avoid leaking duplicated GtkStack pages each time the + * templates menu is set. Unbinding the model is the only way to clear + * all children. For that reason, we need to rebind the popover before + * it is shown again. + * See https://gitlab.gnome.org/GNOME/nautilus/-/issues/1705 */ + gtk_popover_bind_model (self->current_view_menu_popover, + G_MENU_MODEL (self->current_view_menu), + NULL); gtk_popover_popup (self->current_view_menu_popover); } else -- cgit v1.2.1