diff options
author | Benjamin Otte <otte@redhat.com> | 2020-06-08 18:47:44 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2020-06-08 19:06:56 +0200 |
commit | 541aaa23920d1e6ac27b186334aadde78a3ecf43 (patch) | |
tree | 222d06dc86c747e25978602fb9137116404dcefc /gtk/gtkmultiselection.c | |
parent | d294b01cee804c95024f1623289686d77c549d62 (diff) | |
download | gtk+-541aaa23920d1e6ac27b186334aadde78a3ecf43.tar.gz |
selectionmodel: Add unselect_rest argument to select_callback
This is not just about consistency with other functions.
It is about avoiding reentrancy problems.
GtkListBase first doing an unselect_all() will then force the
SelectionModel to consider a state where all items are unselected
(and potentially deciding to autoselect one) and then cause a
"selection-changed" emission that unselects all items and potentially
updates all the list item widgets in the GtkListBase to the unselected
state.
After this, GtkListBase selects new items, but to the SelectionModel and
the list item widgets this looks like an enitrely new operation and
there is no way to associate it with the previous state, so the
SelectionModel cannot undo any previous actions it took when
unselecting.
And all listitem widgets will now think they were just selected and
start running animations about selecting.
Diffstat (limited to 'gtk/gtkmultiselection.c')
-rw-r--r-- | gtk/gtkmultiselection.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/gtk/gtkmultiselection.c b/gtk/gtkmultiselection.c index a852972bee..70045b525c 100644 --- a/gtk/gtkmultiselection.c +++ b/gtk/gtkmultiselection.c @@ -175,6 +175,7 @@ gtk_multi_selection_unselect_all (GtkSelectionModel *model) static gboolean gtk_multi_selection_add_or_remove (GtkSelectionModel *model, + gboolean unselect_rest, gboolean add, GtkSelectionCallback callback, gpointer data) @@ -190,6 +191,13 @@ gtk_multi_selection_add_or_remove (GtkSelectionModel *model, min = G_MAXUINT; max = 0; + if (unselect_rest) + { + min = gtk_set_get_min (self->selected); + max = gtk_set_get_max (self->selected); + gtk_set_remove_all (self->selected); + } + for (pos = 0; pos < n; pos = start + n_items) { callback (pos, &start, &n_items, &in, data); @@ -223,10 +231,11 @@ gtk_multi_selection_add_or_remove (GtkSelectionModel *model, static gboolean gtk_multi_selection_select_callback (GtkSelectionModel *model, + gboolean unselect_rest, GtkSelectionCallback callback, gpointer data) { - return gtk_multi_selection_add_or_remove (model, TRUE, callback, data); + return gtk_multi_selection_add_or_remove (model, unselect_rest, TRUE, callback, data); } static gboolean @@ -234,7 +243,7 @@ gtk_multi_selection_unselect_callback (GtkSelectionModel *model, GtkSelectionCallback callback, gpointer data) { - return gtk_multi_selection_add_or_remove (model, FALSE, callback, data); + return gtk_multi_selection_add_or_remove (model, FALSE, FALSE, callback, data); } static void |