[gtk/selection-changed-fixups] selection: Emit ::selection-changed for autoselection



commit 088f7331f92b3a107b222a3b4761fb13bb3e8f8f
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Dec 21 20:31:52 2019 -0500

    selection: Emit ::selection-changed for autoselection
    
    If a single selection gains a selected item because the
    underlying model goes from empty to non-empty, and the
    selection is set to autoselect, emit ::selection-changed.
    
    Update the existing tests that were previously checking
    the wrong thing, and add a new test specifically for this.

 gtk/gtksingleselection.c        | 30 ++++++++++++++++++++-------
 testsuite/gtk/singleselection.c | 46 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 67 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtksingleselection.c b/gtk/gtksingleselection.c
index 63db37d0de..727cf0416c 100644
--- a/gtk/gtksingleselection.c
+++ b/gtk/gtksingleselection.c
@@ -192,6 +192,21 @@ G_DEFINE_TYPE_EXTENDED (GtkSingleSelection, gtk_single_selection, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (GTK_TYPE_SELECTION_MODEL,
                                                gtk_single_selection_selection_model_init))
 
+static void
+emit_selection_changed (GtkSelectionModel *self,
+                        int                old_position,
+                        int                position)
+{
+  if (old_position == GTK_INVALID_LIST_POSITION)
+    gtk_selection_model_selection_changed (self, position, 1);
+  else if (position == GTK_INVALID_LIST_POSITION)
+    gtk_selection_model_selection_changed (self, old_position, 1);
+  else if (position < old_position)
+    gtk_selection_model_selection_changed (self, position, old_position - position + 1);
+  else
+    gtk_selection_model_selection_changed (self, old_position, position - old_position + 1);
+}
+
 static void
 gtk_single_selection_items_changed_cb (GListModel         *model,
                                        guint               position,
@@ -200,6 +215,9 @@ gtk_single_selection_items_changed_cb (GListModel         *model,
                                        GtkSingleSelection *self)
 {
   g_object_freeze_notify (G_OBJECT (self));
+  int selected_before;
+
+  selected_before = self->selected;
 
   if (self->selected_item == NULL)
     {
@@ -295,6 +313,9 @@ gtk_single_selection_items_changed_cb (GListModel         *model,
 
   g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
 
+  if (self->selected != selected_before)
+    emit_selection_changed (GTK_SELECTION_MODEL (self), selected_before, self->selected);
+
   g_object_thaw_notify (G_OBJECT (self));
 }
 
@@ -563,14 +584,7 @@ gtk_single_selection_set_selected (GtkSingleSelection *self,
   g_clear_object (&self->selected_item);
   self->selected_item = new_selected;
 
-  if (old_position == GTK_INVALID_LIST_POSITION)
-    gtk_selection_model_selection_changed (GTK_SELECTION_MODEL (self), position, 1);
-  else if (position == GTK_INVALID_LIST_POSITION)
-    gtk_selection_model_selection_changed (GTK_SELECTION_MODEL (self), old_position, 1);
-  else if (position < old_position)
-    gtk_selection_model_selection_changed (GTK_SELECTION_MODEL (self), position, old_position - position + 
1);
-  else
-    gtk_selection_model_selection_changed (GTK_SELECTION_MODEL (self), old_position, position - old_position 
+ 1);
+  emit_selection_changed (GTK_SELECTION_MODEL (self), old_position, position);
 
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]);
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]);
diff --git a/testsuite/gtk/singleselection.c b/testsuite/gtk/singleselection.c
index 24de458e1c..f92e09f6dd 100644
--- a/testsuite/gtk/singleselection.c
+++ b/testsuite/gtk/singleselection.c
@@ -425,7 +425,7 @@ test_autoselect (void)
   assert_model (selection, "1");
   assert_changes (selection, "+0");
   assert_selection (selection, "1");
-  assert_selection_changes (selection, "");
+  assert_selection_changes (selection, "0:1");
 
   splice (store, 0, 1, (guint[]) { 7, 8, 9 }, 3);
   assert_model (selection, "7 8 9");
@@ -642,6 +642,49 @@ test_query_range (void)
   g_object_unref (selection);
 }
 
+static void
+selection_changed_cb (GtkSelectionModel *model,
+                      guint position,
+                      guint n_items,
+                      gpointer data)
+{
+  int *counter = data;
+
+  (*counter)++;
+}
+
+/* Test that the selection emits selection-changed when an item
+ * is autoselected due to the underlying store going from empty
+ * to non-empty.
+ */
+static void
+test_empty (void)
+{
+  GListStore *store;
+  GtkSingleSelection *selection;
+  int counter;
+  GtkFilter *filter;
+
+  store = g_list_store_new (GTK_TYPE_FILTER);
+  
+  counter = 0;
+  selection = gtk_single_selection_new (G_LIST_MODEL (store));
+  g_signal_connect (selection, "selection-changed", G_CALLBACK (selection_changed_cb), &counter);
+
+  g_assert_cmpint (gtk_single_selection_get_selected (GTK_SINGLE_SELECTION (selection)), ==, 
GTK_INVALID_LIST_POSITION);
+
+  filter = gtk_string_filter_new ();
+  g_list_store_append (store, filter);
+  g_object_unref (filter);
+
+  g_assert_cmpint (gtk_single_selection_get_selected (GTK_SINGLE_SELECTION (selection)), ==, 0);
+
+  g_assert_cmpint (counter, ==, 1);
+
+  g_object_unref (selection);
+  g_object_unref (store);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -660,6 +703,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/singleselection/persistence", test_persistence);
   g_test_add_func ("/singleselection/query-range", test_query_range);
   g_test_add_func ("/singleselection/changes", test_changes);
+  g_test_add_func ("/singleselection/empty", test_empty);
 
   return g_test_run ();
 }


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