[nautilus/wip/corey/fix-sort: 1/2] list-view: Keep track of the most recently sorted column




commit 1cdd603dc0f93bfd83873b6ff9c27eb2dda277f4
Author: Corey Berla <corey berla me>
Date:   Thu Oct 13 13:39:50 2022 -0700

    list-view: Keep track of the most recently sorted column
    
    In GtkColumnView, we don't know what column is being sorted on
    from clicking on the column headers.  This means that we can only
    save the sort order when the sort is intiated from the toolbar
    menu rather than the column headers.  As a workaround, keep
    track of the most recently used attribute used in the sorter.
    Then when ::changed is emmited on the sorter, update the metadata
    for what was used while sorting.  This is a pretty bad hack, but the
    current state is worse because
    1) The sort order is never saved in column view
    2) If the sort order was changed (i.e. in GridView), the user
    can't figure out why the order keeps reverting back to another state.

 src/nautilus-list-view.c | 78 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 64 insertions(+), 14 deletions(-)
---
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index 67cdcea21..5793e1fcd 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -37,6 +37,8 @@ struct _NautilusListView
     gint zoom_level;
 
     gboolean directories_first;
+    GQuark sort_attribute;
+    gboolean column_header_was_clicked;
 
     GQuark path_attribute_q;
     GFile *file_path_base_location;
@@ -246,6 +248,12 @@ real_scroll_to_item (NautilusListBase *list_base_view,
     }
 }
 
+typedef struct
+{
+    GQuark attribute;
+    NautilusListView *view;
+} SortData;
+
 static gint
 nautilus_list_view_sort (gconstpointer a,
                          gconstpointer b,
@@ -253,7 +261,15 @@ nautilus_list_view_sort (gconstpointer a,
 {
     NautilusFile *file_a = NAUTILUS_FILE_FROM_FILE_OR_ITEM ((gpointer) a);
     NautilusFile *file_b = NAUTILUS_FILE_FROM_FILE_OR_ITEM ((gpointer) b);
-    GQuark attribute_q = GPOINTER_TO_UINT (user_data);
+    SortData *data = user_data;
+    GQuark attribute_q = data->attribute;
+    NautilusListView *self = data->view;
+
+    /* Hack: We don't know what column is being sorted on when the column
+     * headers are clicked. So let's just look at what attribute was most
+     * recently used for sorting.
+     * https://gitlab.gnome.org/GNOME/gtk/-/issues/4833 */
+    self->sort_attribute = attribute_q;
 
     g_return_val_if_fail (file_a != NULL && file_b != NULL, GTK_ORDERING_EQUAL);
 
@@ -679,12 +695,18 @@ action_sort_order_changed (GSimpleAction *action,
     model = nautilus_list_base_get_model (NAUTILUS_LIST_BASE (self));
     sorter = nautilus_view_model_get_sorter (model);
 
-    g_signal_handlers_block_by_func (sorter, on_sorter_changed, self);
-    /* FIXME: Set NULL to stop drawing the arrow on previous sort column
-     * to workaround https://gitlab.gnome.org/GNOME/gtk/-/issues/4696 */
-    gtk_column_view_sort_by_column (self->view_ui, NULL, FALSE);
-    gtk_column_view_sort_by_column (self->view_ui, sort_column, reversed);
-    g_signal_handlers_unblock_by_func (sorter, on_sorter_changed, self);
+    /* Ask the column view to sort by column if it hasn't just done so already. */
+    if (!self->column_header_was_clicked)
+    {
+        g_signal_handlers_block_by_func (sorter, on_sorter_changed, self);
+        /* FIXME: Set NULL to stop drawing the arrow on previous sort column
+         * to workaround https://gitlab.gnome.org/GNOME/gtk/-/issues/4696 */
+        gtk_column_view_sort_by_column (self->view_ui, NULL, FALSE);
+        gtk_column_view_sort_by_column (self->view_ui, sort_column, reversed);
+        g_signal_handlers_unblock_by_func (sorter, on_sorter_changed, self);
+    }
+
+    self->column_header_was_clicked = FALSE;
 
     set_directory_sort_metadata (nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (self)),
                                  target_name,
@@ -751,6 +773,7 @@ real_begin_loading (NautilusFilesView *files_view)
     NAUTILUS_FILES_VIEW_CLASS (nautilus_list_view_parent_class)->begin_loading (files_view);
 
     update_columns_settings_from_metadata_and_preferences (self);
+    self->sort_attribute = 0;
 
     self->path_attribute_q = 0;
     g_clear_object (&self->file_path_base_location);
@@ -859,12 +882,34 @@ on_sorter_changed (GtkSorter       *sorter,
                    gpointer         user_data)
 {
     NautilusListView *self = NAUTILUS_LIST_VIEW (user_data);
+    NautilusFile *file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (self));
+    const gchar *new_sort_text;
+    gboolean reversed;
+    g_autofree gchar *current_sort_text = NULL;
+
+    if (self->sort_attribute == 0)
+    {
+        new_sort_text = "unknown";
+    }
+    else
+    {
+        new_sort_text = g_quark_to_string (self->sort_attribute);
+    }
+
+    current_sort_text = nautilus_file_get_metadata (file,
+                                                    NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY,
+                                                    "unknown");
 
-    /* When user clicks a header to change sort order, we don't know what the
-     * new sort order is. Make sure the sort menu doesn't indicate a outdated
-     * action state. */
+    if (g_strcmp0 (new_sort_text, current_sort_text) == 0)
+    {
+        reversed = !nautilus_file_get_boolean_metadata (file,
+                                                        NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED,
+                                                        FALSE);
+    }
+
+    self->column_header_was_clicked = TRUE;
     g_action_group_change_action_state (nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (self)),
-                                        "sort", g_variant_new ("(sb)", "unknown", FALSE));
+                                        "sort", g_variant_new ("(sb)", new_sort_text, reversed));
 }
 
 static guint
@@ -1032,6 +1077,7 @@ setup_view_columns (NautilusListView *self)
     for (GList *l = nautilus_columns; l != NULL; l = l->next)
     {
         NautilusColumn *nautilus_column = NAUTILUS_COLUMN (l->data);
+        SortData *data;
         g_autofree gchar *name = NULL;
         g_autofree gchar *label = NULL;
         GQuark attribute_q = 0;
@@ -1046,9 +1092,13 @@ setup_view_columns (NautilusListView *self)
                       "default-sort-order", &sort_order,
                       NULL);
 
+        data = g_new0 (SortData, 1);
+        data->attribute = attribute_q;
+        data->view = self;
+
         sorter = gtk_custom_sorter_new (nautilus_list_view_sort,
-                                        GUINT_TO_POINTER (attribute_q),
-                                        NULL);
+                                        data,
+                                        g_free);
 
         factory = gtk_signal_list_item_factory_new ();
         view_column = gtk_column_view_column_new (NULL, factory);
@@ -1121,7 +1171,7 @@ nautilus_list_view_init (NautilusListView *self)
     sorter = gtk_multi_sorter_new ();
     gtk_multi_sorter_append (sorter, g_object_ref (GTK_SORTER (directories_sorter)));
     gtk_multi_sorter_append (sorter, g_object_ref (gtk_column_view_get_sorter (self->view_ui)));
-    g_signal_connect_object (sorter, "changed", G_CALLBACK (on_sorter_changed), self, 0);
+    g_signal_connect_object (sorter, "changed", G_CALLBACK (on_sorter_changed), self, G_CONNECT_AFTER);
 
     model = nautilus_list_base_get_model (NAUTILUS_LIST_BASE (self));
     nautilus_view_model_set_sorter (model, GTK_SORTER (sorter));


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