[nautilus/wip/corey/fix-sort: 5/5] list-view: Don't create unnecessary LabelCells




commit 185e3ee31bcb3c64267bb2939a502d1c8dd32c3e
Author: Corey Berla <corey berla me>
Date:   Tue Sep 27 15:27:32 2022 -0700

    list-view: Don't create unnecessary LabelCells
    
    In a nautilus-list-view, we create factories for the various
    cells within each GtkListItem.  This is designed with performance in
    mind... we don't want to create hundreds of thounsands of objects
    in a folder where we may only look at the first 50 files.
    
    We are proactively creating every possibly LabelCell without
    checking which one is visible.  This means that even though
    the GtkListView may only request a couple hundred ListItems,
    we end up generating thousands of LabelCells.  There are currently
    13 available columns of which 3 are enabled by default.
    
    Create LabelCells on demand when they are visible, either during
    the loading of a folder or when columns are added.
    
    Fixes: https://gitlab.gnome.org/GNOME/nautilus/-/issues/2498

 src/nautilus-list-view.c | 56 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 49 insertions(+), 7 deletions(-)
---
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index a900a8537..6227dcaa5 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -52,6 +52,8 @@ G_DEFINE_TYPE (NautilusListView, nautilus_list_view, NAUTILUS_TYPE_LIST_BASE)
 static void on_sorter_changed (GtkSorter      *sorter,
                                GtkSorterChange change,
                                gpointer        user_data);
+static void setup_view_columns (NautilusListView *self,
+                                GStrv             column_chooser_columns);
 
 static const char *default_columns_for_recent[] =
 {
@@ -498,6 +500,9 @@ column_chooser_changed_callback (NautilusColumnChooser *chooser,
                                      NAUTILUS_METADATA_KEY_LIST_VIEW_COLUMN_ORDER,
                                      column_order);
 
+    /* Pass the visible columns since the nautilus_file is set async */
+    setup_view_columns (view, visible_columns);
+
     apply_columns_settings (view, column_order, visible_columns);
 
     g_strfreev (visible_columns);
@@ -774,6 +779,8 @@ real_begin_loading (NautilusFilesView *files_view)
 
     NAUTILUS_FILES_VIEW_CLASS (nautilus_list_view_parent_class)->begin_loading (files_view);
 
+    setup_view_columns (self, NULL);
+
     update_columns_settings_from_metadata_and_preferences (self);
 
     self->path_attribute_q = 0;
@@ -1041,17 +1048,27 @@ setup_label_cell (GtkSignalListItemFactory *factory,
 }
 
 static void
-setup_view_columns (NautilusListView *self)
+setup_view_columns (NautilusListView *self,
+                    GStrv             column_chooser_columns)
 {
     GtkListItemFactory *factory;
     g_autolist (NautilusColumn) nautilus_columns = NULL;
+    g_auto (GStrv) visible_columns = get_visible_columns (self);
+    g_autoptr (GList) existing_columns = NULL;  /* Data is owned by the instance */
 
     nautilus_columns = nautilus_get_all_columns ();
 
-    self->factory_to_column_map = g_hash_table_new_full (g_direct_hash,
-                                                         g_direct_equal,
-                                                         NULL,
-                                                         g_object_unref);
+    if (self->factory_to_column_map == NULL)
+    {
+        self->factory_to_column_map = g_hash_table_new_full (g_direct_hash,
+                                                             g_direct_equal,
+                                                             NULL,
+                                                             g_object_unref);
+    }
+    else
+    {
+        existing_columns = g_hash_table_get_values (self->factory_to_column_map);
+    }
 
     for (GList *l = nautilus_columns; l != NULL; l = l->next)
     {
@@ -1062,6 +1079,7 @@ setup_view_columns (NautilusListView *self)
         GtkSortType sort_order;
         g_autoptr (GtkCustomSorter) sorter = NULL;
         g_autoptr (GtkColumnViewColumn) view_column = NULL;
+        gboolean already_generated = FALSE;
 
         g_object_get (nautilus_column,
                       "name", &name,
@@ -1070,6 +1088,32 @@ setup_view_columns (NautilusListView *self)
                       "default-sort-order", &sort_order,
                       NULL);
 
+        if (!g_strv_contains ((const gchar * const *) visible_columns, name))
+        {
+            /* Don't bother generating a bunch of objects for columns that may never be visible */
+            if (column_chooser_columns == NULL)
+            {
+                continue;
+            }
+            else if (!g_strv_contains ((const gchar * const *) column_chooser_columns, name))
+            {
+                continue;
+            }
+        }
+
+        for (GList *col = existing_columns; col != NULL; col = col->next)
+        {
+            if (col->data == nautilus_column)
+            {
+                already_generated = TRUE;
+                break;
+            }
+        }
+        if (already_generated)
+        {
+            continue;
+        }
+
         sorter = gtk_custom_sorter_new (nautilus_list_view_sort,
                                         GUINT_TO_POINTER (attribute_q),
                                         NULL);
@@ -1137,8 +1181,6 @@ nautilus_list_view_init (NautilusListView *self)
     self->view_ui = create_view_ui (self);
     nautilus_list_base_setup_gestures (NAUTILUS_LIST_BASE (self));
 
-    setup_view_columns (self);
-
     self->directories_first = nautilus_files_view_should_sort_directories_first (NAUTILUS_FILES_VIEW (self));
     directories_sorter = gtk_custom_sorter_new (sort_directories_func, &self->directories_first, NULL);
 


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