From: Will Thompson Date: Fri, 3 Mar 2023 13:17:18 +0000 Subject: keyboard: Resort & refilter list when picking shortlist Each row of the keyboard layout/input method list has a flag for whether it is an "extra" layout, hidden by default, or not. All rows are added with the is_extra flag set to TRUE; later, they can be marked as non-extra in a few ways: - The currently-selected layout is (indirectly) marked as non-extra - Selecting a layout marks it as non-extra - 5 semi-arbitrary layouts are marked as non-extra To make the list work, the GtkListBox has sort and filter functions set: - The sort function sorts extra layouts after non-extra layouts - The filter function hides extra layouts, unless the user is searching or has clicked the vertical ellipsis to see all layouts But previously, the sort and filter of the list were not always invalidated when one or more layouts' is_extra flags were changed. As a result, the list always showed no layouts by default, just the vertical ellipsis to see all layouts. Fix this by invalidating both sort and filter when a layout is marked non-extra. Bug: https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/165 Origin: upstream, 44.rc, commit:151688f670e8c6f5ecc8a7bac686ddcc815cdf11 --- .../pages/keyboard/cc-input-chooser.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/gnome-initial-setup/pages/keyboard/cc-input-chooser.c b/gnome-initial-setup/pages/keyboard/cc-input-chooser.c index efba249..2dd58e9 100644 --- a/gnome-initial-setup/pages/keyboard/cc-input-chooser.c +++ b/gnome-initial-setup/pages/keyboard/cc-input-chooser.c @@ -259,6 +259,7 @@ sync_all_checkmarks (CcInputChooser *chooser) { CcInputChooserPrivate *priv; GtkWidget *row; + gboolean invalidate = FALSE; priv = cc_input_chooser_get_instance_private (chooser); row = gtk_widget_get_first_child (priv->input_list); @@ -271,7 +272,7 @@ sync_all_checkmarks (CcInputChooser *chooser) widget = get_input_widget (child); if (widget == NULL) - return; + break; if (priv->id == NULL || priv->type == NULL) should_be_visible = FALSE; @@ -280,13 +281,20 @@ sync_all_checkmarks (CcInputChooser *chooser) g_strcmp0 (widget->type, priv->type) == 0; gtk_widget_set_opacity (widget->checkmark, should_be_visible ? 1.0 : 0.0); - if (widget->is_extra && should_be_visible) + if (widget->is_extra && should_be_visible) { + g_debug ("Marking selected layout %s (%s:%s) as non-extra", + widget->name, widget->type, widget->id); widget->is_extra = FALSE; + invalidate = TRUE; + } row = gtk_widget_get_next_sibling (row); } - gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->input_list)); + if (invalidate) { + gtk_list_box_invalidate_sort (GTK_LIST_BOX (priv->input_list)); + gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->input_list)); + } } static GtkWidget * @@ -344,10 +352,18 @@ choose_non_extras (CcInputChooser *chooser) if (widget == NULL) break; + g_debug ("Picking %s (%s:%s) as non-extra", + widget->name, widget->type, widget->id); widget->is_extra = FALSE; row = gtk_widget_get_next_sibling (row); } + + /* Changing is_extra above affects the ordering and the visibility + * of the newly non-extra rows. + */ + gtk_list_box_invalidate_sort (GTK_LIST_BOX (priv->input_list)); + gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->input_list)); } static void