singleselection: Be more careful about notifies
authorBenjamin Otte <otte@redhat.com>
Mon, 17 Oct 2022 17:54:40 +0000 (19:54 +0200)
committerBenjamin Otte <otte@redhat.com>
Mon, 17 Oct 2022 18:11:27 +0000 (20:11 +0200)
We don't want to notify::selected or notify::selected-item if they
didn't change.
This will bring performance benefits on frequently changing lists.

In particular, if lists get filtered or reordered, but the selected item
stays in the list, not doing a notify::selected-item will avoid updates
in connected handlers like GtkDropdown (and its handlers), thereby
avoiding lots of unnecessary updates.

gtk/gtksingleselection.c

index fb5c1ad435e94aad444c5af1e357e71fe19ffc2f..7e06575872176d59695f298725205d4167f4a79c 100644 (file)
@@ -200,7 +200,6 @@ gtk_single_selection_items_changed_cb (GListModel         *model,
     {
       self->selected += added - removed;
       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]);
-      g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]);
     }
   else
     {
@@ -216,7 +215,6 @@ gtk_single_selection_items_changed_cb (GListModel         *model,
                 {
                   self->selected = position + i;
                   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]);
-                  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]);
                 }
 
               g_object_unref (item);
@@ -226,6 +224,8 @@ gtk_single_selection_items_changed_cb (GListModel         *model,
         }
       if (i == added)
         {
+          guint old_selected = self->selected;
+
           /* the item really was deleted */
           g_clear_object (&self->selected_item);
           if (self->autoselect)
@@ -266,7 +266,9 @@ gtk_single_selection_items_changed_cb (GListModel         *model,
               g_clear_object (&self->selected_item);
               self->selected = GTK_INVALID_LIST_POSITION;
             }
-          g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]);
+          if (old_selected != self->selected)
+            g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]);
+          /* the item was deleted above, so this is guaranteed to be new, even if the position didn't change */
           g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]);
         }
     }