[nautilus/1705-memory-leak-on-each-tab-switch-causes-tab-switching-in-3-38-2-to-become-slow-takes-1-second: 16/16] pathbar: Avoid leaking stack pages




commit c56e90ed699d155a5653d1b703ad4e41bcf4aa7f
Author: António Fernandes <antoniof gnome org>
Date:   Tue Oct 26 12:20:57 2021 +0100

    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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]