diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-12-21 20:31:52 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-05-31 13:03:56 -0400 |
commit | 088f7331f92b3a107b222a3b4761fb13bb3e8f8f (patch) | |
tree | 26da4fc672d010018560a841b059ebf3d06e046b | |
parent | 93353888ca787a4c94a39751beccc160d85f9a61 (diff) | |
download | gtk+-selection-changed-fixups.tar.gz |
selection: Emit ::selection-changed for autoselectionselection-changed-fixups
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.
-rw-r--r-- | gtk/gtksingleselection.c | 30 | ||||
-rw-r--r-- | 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 @@ -193,6 +193,21 @@ G_DEFINE_TYPE_EXTENDED (GtkSingleSelection, gtk_single_selection, G_TYPE_OBJECT, 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, guint removed, @@ -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 (); } |