sortlistmodel: Optimize signals
authorMatthias Clasen <mclasen@redhat.com>
Sat, 27 May 2023 23:40:20 +0000 (19:40 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Sun, 28 May 2023 00:37:28 +0000 (20:37 -0400)
When we emit items-changed due to a section
sorter change, don't also emit sections-changed.
Instead make the items-changed signal cover the
whole range.

Tests included.

gtk/gtksortlistmodel.c
testsuite/gtk/sortlistmodel.c

index 8d05d30407a3b4b0e9e1fff799e083ee2363afd7..61ca5a8c64d004bbe799fc30727bfd669170a577 100644 (file)
@@ -873,9 +873,10 @@ gtk_sort_list_model_get_property (GObject     *object,
 }
 
 static void
-gtk_sort_list_model_sorter_changed_cb (GtkSorter        *sorter,
-                                       int               change,
-                                       GtkSortListModel *self)
+gtk_sort_list_model_sorter_changed (GtkSorter        *sorter,
+                                    int               change,
+                                    GtkSortListModel *self,
+                                    gboolean          sections_changed)
 {
   guint pos, n_items;
 
@@ -928,8 +929,25 @@ gtk_sort_list_model_sorter_changed_cb (GtkSorter        *sorter,
       gtk_sort_list_model_clear_items (self, &pos, &n_items);
     }
 
-  if (n_items > 0)
-    g_list_model_items_changed (G_LIST_MODEL (self), pos, n_items, n_items);
+  if (sections_changed && self->n_items > 0)
+    {
+      if (n_items > 0)
+        g_list_model_items_changed (G_LIST_MODEL (self), 0, self->n_items, self->n_items);
+      else
+        gtk_section_model_sections_changed (GTK_SECTION_MODEL (self), 0, self->n_items);
+    }
+  else if (n_items > 0)
+    {
+      g_list_model_items_changed (G_LIST_MODEL (self), pos, n_items, n_items);
+    }
+}
+
+static void
+gtk_sort_list_model_sorter_changed_cb (GtkSorter        *sorter,
+                                       int               change,
+                                       GtkSortListModel *self)
+{
+  gtk_sort_list_model_sorter_changed (sorter, change, self, FALSE);
 }
 
 static void
@@ -955,7 +973,8 @@ gtk_sort_list_model_clear_real_sorter (GtkSortListModel *self)
 }
 
 static void
-gtk_sort_list_model_ensure_real_sorter (GtkSortListModel *self)
+gtk_sort_list_model_ensure_real_sorter (GtkSortListModel *self,
+                                        gboolean          sections_changed)
 {
   if (self->sorter)
     {
@@ -980,7 +999,7 @@ gtk_sort_list_model_ensure_real_sorter (GtkSortListModel *self)
   if (self->real_sorter)
     g_signal_connect (self->real_sorter, "changed", G_CALLBACK (gtk_sort_list_model_sorter_changed_cb), self);
 
-  gtk_sort_list_model_sorter_changed_cb (self->real_sorter, GTK_SORTER_CHANGE_DIFFERENT, self);
+  gtk_sort_list_model_sorter_changed (self->real_sorter, GTK_SORTER_CHANGE_DIFFERENT, self, sections_changed);
 }
 
 static void
@@ -1202,7 +1221,7 @@ gtk_sort_list_model_set_sorter (GtkSortListModel *self,
 
   gtk_sort_list_model_clear_real_sorter (self);
   g_set_object (&self->sorter, sorter);
-  gtk_sort_list_model_ensure_real_sorter (self);
+  gtk_sort_list_model_ensure_real_sorter (self, FALSE);
 
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SORTER]);
 }
@@ -1244,10 +1263,7 @@ gtk_sort_list_model_set_section_sorter (GtkSortListModel *self,
 
   gtk_sort_list_model_clear_real_sorter (self);
   g_set_object (&self->section_sorter, sorter);
-  gtk_sort_list_model_ensure_real_sorter (self);
-
-  if (self->n_items > 0)
-    gtk_section_model_sections_changed (GTK_SECTION_MODEL (self), 0, self->n_items);
+  gtk_sort_list_model_ensure_real_sorter (self, TRUE);
 
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SECTION_SORTER]);
 }
index d3e6e558db31b156346d1fc21d8242c5f11fce30..b0b85117ed9bcdec1d14a3496511524bba3afc90 100644 (file)
@@ -648,6 +648,22 @@ by_n (gconstpointer p1,
     return 0;
 }
 
+static int
+weird (gconstpointer p1,
+       gconstpointer p2,
+       gpointer      data)
+{
+  guint n1 = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (p1), number_quark));
+  guint n2 = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (p2), number_quark));
+
+  if (n1 == 5 && n2 != 5)
+    return -1;
+  else if (n1 != 5 && n2 == 5)
+    return 1;
+
+  return by_n (p1, p2, data);
+}
+
 static void
 test_sections (void)
 {
@@ -680,6 +696,13 @@ test_sections (void)
   assert_changes (model, "s0:10");
   assert_section_model (model, "[1 2 3 4] [5 6 7 8 9] [10]");
 
+  sorter = GTK_SORTER (gtk_custom_sorter_new (weird, GUINT_TO_POINTER (5), NULL));
+  gtk_sort_list_model_set_section_sorter (model, sorter);
+  g_object_unref (sorter);
+
+  assert_changes (model, "0-10+10");
+  assert_section_model (model, "[5] [1 2 3 4] [6 7 8 9] [10]");
+
   g_object_unref (store);
   g_object_unref (model);
 }