Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: gnome-initial-se...@packages.debian.org
Control: affects -1 + src:gnome-initial-setup

Please unblock package gnome-initial-setup

[ Reason ]
Fix UI glitches observed while testing fixes for #1029821

[ Impact ]
If not fixed, the full-screen "out of box experience" app shown on the
first login to GNOME, after initial installation or creating a new user,
is less polished than it should be.

The main fix since bookworm is that for users in locales that use a
non-trivial IBus input method rather than a simple Xkb keyboard layout
(Chinese, Japanese, Hindi, etc.), the default input method was mislabelled
and did not always appear. (#1032382)

This version also has an upstream change backported from upstream version
44.rc, fixing a regression that caused the shortlist of plausible
non-default keyboard layouts and input methods to be empty. There is
still a known bug that the shortlist is not very *useful* (it does not
have enough information to be weighted towards commonly-used keyboard
layouts and input methods for the relevant country, and away from
rare/specialized layouts like Dvorak), but that's not a regression and
it's better than nothing.

It also includes smaller tweaks to ensure the gnome-initial-setup window
is appropriately labelled in Alt+Tab and the Overview.

[ Tests ]
Manually tested via the steps in debian/README.source of unstable's
gnome-initial-setup, using English and Japanese locales.

Also carried out an installation of bookworm in Japanese (using a
parallel installation in English as a reference for which button does
what) and before logging in to GNOME for the first time, logged in via
tty to upgrade gnome-initial-setup and all packages from src:gnome-desktop
to their unstable versions.

[ Risks ]
This is a highly visible package with code that is surprisingly
fragile internally, and my initial attempt at this patchset caused it
to crash; but I expect that a lot of people will be testing new GNOME
installs between now and release day, so we'll get regression reports
if appropriate.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

unblock gnome-initial-setup/43.2-4
diffstat for gnome-initial-setup-43.2 gnome-initial-setup-43.2

 data/gnome-initial-setup.desktop.in.in                                         |    1 
 debian/README.source                                                           |   19 +
 debian/changelog                                                               |   52 ++
 debian/control                                                                 |    2 
 debian/patches/Add-StartupWMClass-to-.desktop-file.patch                       |   29 +
 debian/patches/driver-Set-a-non-trivial-window-title.patch                     |   28 +
 debian/patches/keyboard-Correctly-update-labels-for-IBus-engines.patch         |  189 ++++++++++
 debian/patches/keyboard-Resort-refilter-list-when-picking-shortlist.patch      |   96 +++++
 debian/patches/keyboard-Update-filter-and-sort-when-the-display-name-cha.patch |   46 ++
 debian/patches/reenable-existing-user-mode.patch                               |    6 
 debian/patches/series                                                          |    5 
 gnome-initial-setup/gis-driver.c                                               |    1 
 gnome-initial-setup/pages/keyboard/cc-input-chooser.c                          |   86 +++-
 13 files changed, 529 insertions(+), 31 deletions(-)

diff -Nru gnome-initial-setup-43.2/data/gnome-initial-setup.desktop.in.in gnome-initial-setup-43.2/data/gnome-initial-setup.desktop.in.in
--- gnome-initial-setup-43.2/data/gnome-initial-setup.desktop.in.in	2022-12-02 15:11:34.000000000 +0000
+++ gnome-initial-setup-43.2/data/gnome-initial-setup.desktop.in.in	2023-03-09 12:51:50.000000000 +0000
@@ -10,3 +10,4 @@
 OnlyShowIn=GNOME;
 NoDisplay=true
 X-GNOME-HiddenUnderSystemd=@systemd_hidden@
+StartupWMClass=org.gnome.InitialSetup
diff -Nru gnome-initial-setup-43.2/debian/changelog gnome-initial-setup-43.2/debian/changelog
--- gnome-initial-setup-43.2/debian/changelog	2022-12-06 14:27:10.000000000 +0000
+++ gnome-initial-setup-43.2/debian/changelog	2023-03-06 23:46:19.000000000 +0000
@@ -1,3 +1,55 @@
+gnome-initial-setup (43.2-4) unstable; urgency=medium
+
+  * Team upload
+  * d/p/keyboard-Resort-refilter-list-when-picking-shortlist.patch:
+    Add patch from upstream 44.rc to display more input methods and
+    keyboard layouts without clicking the "more..." button. This has
+    a known issue that the shortlist of keyboard layouts is often not
+    particularly useful, but at least it includes the default and
+    current layouts (possibly different) and some other possibilities.
+  * d/p/keyboard-Correctly-update-labels-for-IBus-engines.patch,
+    d/p/keyboard-Update-filter-and-sort-when-the-display-name-cha.patch:
+    Rework patches for xkb layout and IBus method selection, fixing a
+    crash on startup (Closes: #1032448)
+  * d/README.source: Add some notes on how to smoke-test this package.
+    Thanks to Jeremy Bicha (via #1032448)
+  * d/p/driver-Set-a-non-trivial-window-title.patch:
+    Add patch to set a window title.
+    This is one of the first things a new GNOME user will see, so let's
+    make it a bit more polished.
+
+ -- Simon McVittie <s...@debian.org>  Mon, 06 Mar 2023 23:46:19 +0000
+
+gnome-initial-setup (43.2-3) unstable; urgency=medium
+
+  * Team upload
+  * d/p/Add-StartupWMClass-to-.desktop-file.patch:
+    Replace previous patch for app ID handling with upstream equivalent.
+    gnome-initial-setup is not a syntactically valid app ID. Return to the
+    syntactically valid app ID used upstream, and set the StartupWMClass
+    instead.
+    This gives us a correct window title in the Overview and the
+    Alt+(key above Tab) window switcher, unlike the patch in 43.2-2.
+  * d/p/reenable-existing-user-mode.patch:
+    Add a note of which upstream commit we're reverting
+  * d/patches: Reorder with closest-to-upstream first
+  * d/p/keyboard-Correctly-update-labels-for-IBus-engines.patch,
+    d/p/keyboard-Update-filter-and-sort-when-the-display-name-cha.patch:
+    Correctly update input method chooser with info from IBus.
+    This ensures that when the default is an IBus-based input method like
+    Anthy (currently GNOME's default for ja_JP in bookworm) or Mozc (requested
+    as a new default for ja_JP in #1029821), it will be displayed with its
+    correct label like "Japanese (Anthy)" or "日本語 (Mozc)" instead of
+    a placeholder name "anthy" or "mozc-jp". (Closes: #1032382)
+
+ -- Simon McVittie <s...@debian.org>  Sun, 05 Mar 2023 17:39:30 +0000
+
+gnome-initial-setup (43.2-2) unstable; urgency=medium
+
+  * Add patch to fix broken icon and app name
+
+ -- Jeremy Bicha <jbi...@ubuntu.com>  Thu, 02 Mar 2023 17:32:26 -0500
+
 gnome-initial-setup (43.2-1) unstable; urgency=medium
 
   * New upstream release
diff -Nru gnome-initial-setup-43.2/debian/control gnome-initial-setup-43.2/debian/control
--- gnome-initial-setup-43.2/debian/control	2022-12-06 14:27:10.000000000 +0000
+++ gnome-initial-setup-43.2/debian/control	2023-03-06 23:46:19.000000000 +0000
@@ -6,7 +6,7 @@
 Section: gnome
 Priority: optional
 Maintainer: Debian GNOME Maintainers <pkg-gnome-maintain...@lists.alioth.debian.org>
-Uploaders: Jeremy Bicha <jbi...@ubuntu.com>, Laurent Bigonville <bi...@debian.org>
+Uploaders: Jeremy Bicha <jbi...@ubuntu.com>
 Build-Depends: debhelper-compat (= 13),
                dh-sequence-gnome,
                gsettings-desktop-schemas-dev (>= 3.37.1),
diff -Nru gnome-initial-setup-43.2/debian/patches/Add-StartupWMClass-to-.desktop-file.patch gnome-initial-setup-43.2/debian/patches/Add-StartupWMClass-to-.desktop-file.patch
--- gnome-initial-setup-43.2/debian/patches/Add-StartupWMClass-to-.desktop-file.patch	1970-01-01 01:00:00.000000000 +0100
+++ gnome-initial-setup-43.2/debian/patches/Add-StartupWMClass-to-.desktop-file.patch	2023-03-06 23:46:19.000000000 +0000
@@ -0,0 +1,29 @@
+From: Will Thompson <w...@endlessos.org>
+Date: Fri, 3 Mar 2023 11:04:52 +0000
+Subject: Add StartupWMClass to .desktop file
+
+Initial Setup's application ID is org.gnome.InitialSetup. This does not
+match the desktop file name. It is too late in the current development
+cycle to rename the desktop file to match.
+
+Instead, allow the shell to associate the initial setup window with its
+desktop file by specifying StartupWMClass.
+
+See https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/179 and
+https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/merge_requests/186
+for more background.
+
+Origin: upstream, 44~rc, commit:87e81b9c80dfb05f43fe62bb5dad62f707f3b824
+---
+ data/gnome-initial-setup.desktop.in.in | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/data/gnome-initial-setup.desktop.in.in b/data/gnome-initial-setup.desktop.in.in
+index e7aa666..c15fd6e 100644
+--- a/data/gnome-initial-setup.desktop.in.in
++++ b/data/gnome-initial-setup.desktop.in.in
+@@ -10,3 +10,4 @@ Categories=GNOME;GTK;System;
+ OnlyShowIn=GNOME;
+ NoDisplay=true
+ X-GNOME-HiddenUnderSystemd=@systemd_hidden@
++StartupWMClass=org.gnome.InitialSetup
diff -Nru gnome-initial-setup-43.2/debian/patches/driver-Set-a-non-trivial-window-title.patch gnome-initial-setup-43.2/debian/patches/driver-Set-a-non-trivial-window-title.patch
--- gnome-initial-setup-43.2/debian/patches/driver-Set-a-non-trivial-window-title.patch	1970-01-01 01:00:00.000000000 +0100
+++ gnome-initial-setup-43.2/debian/patches/driver-Set-a-non-trivial-window-title.patch	2023-03-06 23:46:19.000000000 +0000
@@ -0,0 +1,28 @@
+From: Simon McVittie <s...@debian.org>
+Date: Mon, 6 Mar 2023 23:34:50 +0000
+Subject: driver: Set a non-trivial window title
+
+When running in "existing user" mode (which isn't done upstream, but
+Debian and Ubuntu re-enable it because they don't have GNOME Tour),
+the window title is visible in Alt+[key above Tab] and the Overview.
+It defaults to "gnome-initial-setup", but looks better if we reuse the
+translated name from the .desktop file.
+
+Signed-off-by: Simon McVittie <s...@debian.org>
+Forwarded: https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/merge_requests/191
+---
+ gnome-initial-setup/gis-driver.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c
+index 1ddf3c6..8459efa 100644
+--- a/gnome-initial-setup/gis-driver.c
++++ b/gnome-initial-setup/gis-driver.c
+@@ -797,6 +797,7 @@ gis_driver_startup (GApplication *app)
+                                     "application", app,
+                                     "icon-name", "preferences-system",
+                                     "deletable", FALSE,
++                                    "title", _("Initial Setup"),
+                                     NULL);
+ 
+   g_signal_connect (driver->main_window,
diff -Nru gnome-initial-setup-43.2/debian/patches/keyboard-Correctly-update-labels-for-IBus-engines.patch gnome-initial-setup-43.2/debian/patches/keyboard-Correctly-update-labels-for-IBus-engines.patch
--- gnome-initial-setup-43.2/debian/patches/keyboard-Correctly-update-labels-for-IBus-engines.patch	1970-01-01 01:00:00.000000000 +0100
+++ gnome-initial-setup-43.2/debian/patches/keyboard-Correctly-update-labels-for-IBus-engines.patch	2023-03-06 23:46:19.000000000 +0000
@@ -0,0 +1,189 @@
+From: Simon McVittie <s...@debian.org>
+Date: Mon, 6 Mar 2023 22:23:28 +0000
+Subject: keyboard: Correctly update labels for IBus engines
+
+After the port from GTK 3 to 4, in general there's an additional level
+of indirection: the children of priv->input_list are GtkListBoxRow
+objects containing the widget whose user-data is the InputWidget. This
+means we didn't find the InputWidget and therefore couldn't update its
+display name.
+
+Unfortunately, there is one exception to the rule that every child
+of a GtkListBox is a GtkListBoxRow: the placeholder object, in our
+case priv->no_results, is not wrapped in a GtkListBoxRow (see also
+GNOME/gtk#4523). This means that walking the GtkWidget tree seems rather
+fragile: it's difficult to tell whether each child of the GtkListBox
+is a GtkListBoxRow, or the placeholder object priv->no_results, or
+some third type of object that could be added by a future GTK version
+(particularly since there is no particular type-safety here).
+
+Instead of walking the widget tree, maintain our own parallel list of
+known keyboard layouts and other input methods. For this list, we can
+safely assert that every item is something that we put there, with the
+invariant that it's a GtkBox with an InputWidget attached.
+
+This means that we can reliably find the InputWidget, and update its
+associated display name.
+
+Fixes: ad500afc "keyboard: Port to GTK4"
+Bug: https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/180
+Signed-off-by: Simon McVittie <s...@debian.org>
+Bug-Debian: https://bugs.debian.org/1032382
+Forwarded: https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/180
+---
+ .../pages/keyboard/cc-input-chooser.c              | 56 ++++++++++++----------
+ 1 file changed, 31 insertions(+), 25 deletions(-)
+
+diff --git a/gnome-initial-setup/pages/keyboard/cc-input-chooser.c b/gnome-initial-setup/pages/keyboard/cc-input-chooser.c
+index 2dd58e9..ae8f2d7 100644
+--- a/gnome-initial-setup/pages/keyboard/cc-input-chooser.c
++++ b/gnome-initial-setup/pages/keyboard/cc-input-chooser.c
+@@ -50,6 +50,7 @@ struct _CcInputChooserPrivate
+ {
+         GtkWidget *filter_entry;
+         GtkWidget *input_list;
++        GPtrArray *input_widget_boxes;
+ 	GHashTable *inputs;
+ 
+         GtkWidget *no_results;
+@@ -96,6 +97,11 @@ typedef struct {
+         gboolean is_extra;
+ } InputWidget;
+ 
++/*
++ * Invariant: for each box in priv->input_widget_boxes,
++ * get_input_widget (row) is non-null and
++ * get_input_widget (row)->box == box
++ */
+ static InputWidget *
+ get_input_widget (GtkWidget *widget)
+ {
+@@ -258,21 +264,20 @@ static void
+ sync_all_checkmarks (CcInputChooser *chooser)
+ {
+         CcInputChooserPrivate *priv;
+-        GtkWidget *row;
+         gboolean invalidate = FALSE;
++        gsize i;
+ 
+         priv = cc_input_chooser_get_instance_private (chooser);
+-        row = gtk_widget_get_first_child (priv->input_list);
+-        while (row) {
++
++        for (i = 0; i < priv->input_widget_boxes->len; i++) {
+                 InputWidget *widget;
+                 GtkWidget *child;
+                 gboolean should_be_visible;
+ 
+-                child = gtk_list_box_row_get_child (GTK_LIST_BOX_ROW (row));
++                child = g_ptr_array_index (priv->input_widget_boxes, i);
+                 widget = get_input_widget (child);
+-
+-                if (widget == NULL)
+-                        break;
++                g_assert (widget != NULL);
++                g_assert (widget->box == child);
+ 
+ 	        if (priv->id == NULL || priv->type == NULL)
+ 		        should_be_visible = FALSE;
+@@ -287,8 +292,6 @@ sync_all_checkmarks (CcInputChooser *chooser)
+                         widget->is_extra = FALSE;
+                         invalidate = TRUE;
+                 }
+-
+-                row = gtk_widget_get_next_sibling (row);
+         }
+ 
+         if (invalidate) {
+@@ -335,28 +338,26 @@ static void
+ choose_non_extras (CcInputChooser *chooser)
+ {
+         CcInputChooserPrivate *priv;
+-        GtkWidget *row;
+         guint count = 0;
++        gsize i;
+ 
+         priv = cc_input_chooser_get_instance_private (chooser);
+-        row = gtk_widget_get_first_child (priv->input_list);
+-        while (row) {
++
++        for (i = 0; i < priv->input_widget_boxes->len; i++) {
+                 InputWidget *widget;
+                 GtkWidget *child;
+ 
+                 if (++count > MIN_ROWS)
+                         break;
+ 
+-                child = gtk_list_box_row_get_child (GTK_LIST_BOX_ROW (row));
++                child = g_ptr_array_index (priv->input_widget_boxes, i);
+                 widget = get_input_widget (child);
+-                if (widget == NULL)
+-                        break;
++                g_assert (widget != NULL);
++                g_assert (widget->box == child);
+ 
+                 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
+@@ -391,6 +392,7 @@ add_rows_to_list (CcInputChooser  *chooser,
+ 		g_hash_table_add (priv->inputs, key);
+ 
+ 		widget = input_widget_new (chooser, type, id, TRUE);
++		g_ptr_array_add (priv->input_widget_boxes, g_object_ref_sink (widget));
+ 		gtk_list_box_append (GTK_LIST_BOX (priv->input_list), widget);
+ 	}
+ }
+@@ -588,21 +590,21 @@ update_ibus_active_sources (CcInputChooser *chooser)
+ {
+         CcInputChooserPrivate *priv;
+         IBusEngineDesc *engine_desc;
+-        GtkWidget *child;
+         const gchar *type;
+         const gchar *id;
+         gchar *name;
++        gsize i;
+ 
+         priv = cc_input_chooser_get_instance_private (chooser);
+-        child = gtk_widget_get_first_child (priv->input_list);
+-        while (child) {
+-                InputWidget *row;
+ 
+-		row = get_input_widget (child);
+-                child = gtk_widget_get_next_sibling (child);
++        for (i = 0; i < priv->input_widget_boxes->len; i++) {
++                GtkWidget *child;
++                InputWidget *row;
+ 
+-		if (row == NULL)
+-			continue;
++                child = g_ptr_array_index (priv->input_widget_boxes, i);
++                row = get_input_widget (child);
++                g_assert (row != NULL);
++                g_assert (row->box == child);
+ 
+                 type = row->type;
+                 id = row->id;
+@@ -774,6 +776,7 @@ cc_input_chooser_finalize (GObject *object)
+ 
+ 	g_clear_object (&priv->xkb_info);
+ 	g_hash_table_unref (priv->inputs);
++        g_clear_pointer (&priv->input_widget_boxes, g_ptr_array_unref);
+ #ifdef HAVE_IBUS
+         g_clear_object (&priv->ibus);
+         if (priv->ibus_cancellable)
+@@ -844,7 +847,10 @@ cc_input_chooser_class_init (CcInputChooserClass *klass)
+ static void
+ cc_input_chooser_init (CcInputChooser *chooser)
+ {
++        CcInputChooserPrivate *priv = cc_input_chooser_get_instance_private (chooser);
++
+         gtk_widget_init_template (GTK_WIDGET (chooser));
++        priv->input_widget_boxes = g_ptr_array_new_with_free_func (g_object_unref);
+ }
+ 
+ void
diff -Nru gnome-initial-setup-43.2/debian/patches/keyboard-Resort-refilter-list-when-picking-shortlist.patch gnome-initial-setup-43.2/debian/patches/keyboard-Resort-refilter-list-when-picking-shortlist.patch
--- gnome-initial-setup-43.2/debian/patches/keyboard-Resort-refilter-list-when-picking-shortlist.patch	1970-01-01 01:00:00.000000000 +0100
+++ gnome-initial-setup-43.2/debian/patches/keyboard-Resort-refilter-list-when-picking-shortlist.patch	2023-03-06 23:46:19.000000000 +0000
@@ -0,0 +1,96 @@
+From: Will Thompson <w...@endlessos.org>
+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
diff -Nru gnome-initial-setup-43.2/debian/patches/keyboard-Update-filter-and-sort-when-the-display-name-cha.patch gnome-initial-setup-43.2/debian/patches/keyboard-Update-filter-and-sort-when-the-display-name-cha.patch
--- gnome-initial-setup-43.2/debian/patches/keyboard-Update-filter-and-sort-when-the-display-name-cha.patch	1970-01-01 01:00:00.000000000 +0100
+++ gnome-initial-setup-43.2/debian/patches/keyboard-Update-filter-and-sort-when-the-display-name-cha.patch	2023-03-06 23:46:19.000000000 +0000
@@ -0,0 +1,46 @@
+From: Simon McVittie <s...@debian.org>
+Date: Sun, 5 Mar 2023 16:16:12 +0000
+Subject: keyboard: Update filter and sort when the display name changes
+
+The display name in `InputWidget.name` can affect `sort_inputs()`
+and `input_visible()`, so we should update it when we replace the
+placeholder display name with the real one, and tell GTK to update its
+state accordingly.
+
+Signed-off-by: Simon McVittie <s...@debian.org>
+Bug-Debian: https://bugs.debian.org/1032382
+Forwarded: https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/180
+---
+ gnome-initial-setup/pages/keyboard/cc-input-chooser.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/gnome-initial-setup/pages/keyboard/cc-input-chooser.c b/gnome-initial-setup/pages/keyboard/cc-input-chooser.c
+index ae8f2d7..b851ec6 100644
+--- a/gnome-initial-setup/pages/keyboard/cc-input-chooser.c
++++ b/gnome-initial-setup/pages/keyboard/cc-input-chooser.c
+@@ -589,6 +589,7 @@ static void
+ update_ibus_active_sources (CcInputChooser *chooser)
+ {
+         CcInputChooserPrivate *priv;
++        gboolean invalidate = FALSE;
+         IBusEngineDesc *engine_desc;
+         const gchar *type;
+         const gchar *id;
+@@ -615,9 +616,16 @@ update_ibus_active_sources (CcInputChooser *chooser)
+                 if (engine_desc) {
+                         name = engine_get_display_name (engine_desc);
+                         gtk_label_set_text (GTK_LABEL (row->label), name);
+-                        g_free (name);
++                        g_clear_pointer (&row->name, g_free);
++                        row->name = g_steal_pointer (&name);
++                        invalidate = TRUE;
+                 }
+         }
++
++        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 void
diff -Nru gnome-initial-setup-43.2/debian/patches/reenable-existing-user-mode.patch gnome-initial-setup-43.2/debian/patches/reenable-existing-user-mode.patch
--- gnome-initial-setup-43.2/debian/patches/reenable-existing-user-mode.patch	2022-12-06 14:27:10.000000000 +0000
+++ gnome-initial-setup-43.2/debian/patches/reenable-existing-user-mode.patch	2023-03-06 23:46:19.000000000 +0000
@@ -2,16 +2,18 @@
 Date: Thu, 17 Feb 2022 08:17:17 -0500
 Subject: Re-enable existing users mode since gnome-tour isn't in Debian
 
+This reverts commit 43f1870c "Disable existing-user mode".
+
 Forwarded: not-needed
 ---
  gnome-initial-setup/gnome-initial-setup.c | 14 --------------
  1 file changed, 14 deletions(-)
 
 diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c
-index fd74bad..dba16e1 100644
+index 113ded3..4d14fea 100644
 --- a/gnome-initial-setup/gnome-initial-setup.c
 +++ b/gnome-initial-setup/gnome-initial-setup.c
-@@ -374,20 +374,6 @@ main (int argc, char *argv[])
+@@ -323,20 +323,6 @@ main (int argc, char *argv[])
    adw_style_manager_set_color_scheme (adw_style_manager_get_default (),
                                        ADW_COLOR_SCHEME_PREFER_LIGHT);
  
diff -Nru gnome-initial-setup-43.2/debian/patches/series gnome-initial-setup-43.2/debian/patches/series
--- gnome-initial-setup-43.2/debian/patches/series	2022-12-06 14:27:10.000000000 +0000
+++ gnome-initial-setup-43.2/debian/patches/series	2023-03-06 23:46:19.000000000 +0000
@@ -1 +1,6 @@
+Add-StartupWMClass-to-.desktop-file.patch
+keyboard-Resort-refilter-list-when-picking-shortlist.patch
+keyboard-Correctly-update-labels-for-IBus-engines.patch
+keyboard-Update-filter-and-sort-when-the-display-name-cha.patch
+driver-Set-a-non-trivial-window-title.patch
 reenable-existing-user-mode.patch
diff -Nru gnome-initial-setup-43.2/debian/README.source gnome-initial-setup-43.2/debian/README.source
--- gnome-initial-setup-43.2/debian/README.source	1970-01-01 01:00:00.000000000 +0100
+++ gnome-initial-setup-43.2/debian/README.source	2023-03-06 23:46:19.000000000 +0000
@@ -0,0 +1,19 @@
+Testing this package
+====================
+
+Test Case 1
+---------------
+rm ~/.config/gnome-initial-setup-done
+Log out then log back in
+gnome-initial-setup should automatically start
+
+Test Case 2
+----------------
+Create a new user
+Log in as the new user
+gnome-initial-setup should automatically start
+
+Test Case 3
+----------------
+Run this command
+/usr/libexec/gnome-initial-setup --existing-user
diff -Nru gnome-initial-setup-43.2/gnome-initial-setup/gis-driver.c gnome-initial-setup-43.2/gnome-initial-setup/gis-driver.c
--- gnome-initial-setup-43.2/gnome-initial-setup/gis-driver.c	2022-12-02 15:11:34.000000000 +0000
+++ gnome-initial-setup-43.2/gnome-initial-setup/gis-driver.c	2023-03-09 12:51:50.000000000 +0000
@@ -797,6 +797,7 @@
                                     "application", app,
                                     "icon-name", "preferences-system",
                                     "deletable", FALSE,
+                                    "title", _("Initial Setup"),
                                     NULL);
 
   g_signal_connect (driver->main_window,
diff -Nru gnome-initial-setup-43.2/gnome-initial-setup/pages/keyboard/cc-input-chooser.c gnome-initial-setup-43.2/gnome-initial-setup/pages/keyboard/cc-input-chooser.c
--- gnome-initial-setup-43.2/gnome-initial-setup/pages/keyboard/cc-input-chooser.c	2022-12-02 15:11:34.000000000 +0000
+++ gnome-initial-setup-43.2/gnome-initial-setup/pages/keyboard/cc-input-chooser.c	2023-03-09 12:51:50.000000000 +0000
@@ -50,6 +50,7 @@
 {
         GtkWidget *filter_entry;
         GtkWidget *input_list;
+        GPtrArray *input_widget_boxes;
 	GHashTable *inputs;
 
         GtkWidget *no_results;
@@ -96,6 +97,11 @@
         gboolean is_extra;
 } InputWidget;
 
+/*
+ * Invariant: for each box in priv->input_widget_boxes,
+ * get_input_widget (row) is non-null and
+ * get_input_widget (row)->box == box
+ */
 static InputWidget *
 get_input_widget (GtkWidget *widget)
 {
@@ -258,20 +264,20 @@
 sync_all_checkmarks (CcInputChooser *chooser)
 {
         CcInputChooserPrivate *priv;
-        GtkWidget *row;
+        gboolean invalidate = FALSE;
+        gsize i;
 
         priv = cc_input_chooser_get_instance_private (chooser);
-        row = gtk_widget_get_first_child (priv->input_list);
-        while (row) {
+
+        for (i = 0; i < priv->input_widget_boxes->len; i++) {
                 InputWidget *widget;
                 GtkWidget *child;
                 gboolean should_be_visible;
 
-                child = gtk_list_box_row_get_child (GTK_LIST_BOX_ROW (row));
+                child = g_ptr_array_index (priv->input_widget_boxes, i);
                 widget = get_input_widget (child);
-
-                if (widget == NULL)
-                        return;
+                g_assert (widget != NULL);
+                g_assert (widget->box == child);
 
 	        if (priv->id == NULL || priv->type == NULL)
 		        should_be_visible = FALSE;
@@ -280,13 +286,18 @@
                                             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;
-
-                row = gtk_widget_get_next_sibling (row);
+                        invalidate = TRUE;
+                }
         }
 
-        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 *
@@ -327,27 +338,33 @@
 choose_non_extras (CcInputChooser *chooser)
 {
         CcInputChooserPrivate *priv;
-        GtkWidget *row;
         guint count = 0;
+        gsize i;
 
         priv = cc_input_chooser_get_instance_private (chooser);
-        row = gtk_widget_get_first_child (priv->input_list);
-        while (row) {
+
+        for (i = 0; i < priv->input_widget_boxes->len; i++) {
                 InputWidget *widget;
                 GtkWidget *child;
 
                 if (++count > MIN_ROWS)
                         break;
 
-                child = gtk_list_box_row_get_child (GTK_LIST_BOX_ROW (row));
+                child = g_ptr_array_index (priv->input_widget_boxes, i);
                 widget = get_input_widget (child);
-                if (widget == NULL)
-                        break;
+                g_assert (widget != NULL);
+                g_assert (widget->box == child);
 
+                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
@@ -375,6 +392,7 @@
 		g_hash_table_add (priv->inputs, key);
 
 		widget = input_widget_new (chooser, type, id, TRUE);
+		g_ptr_array_add (priv->input_widget_boxes, g_object_ref_sink (widget));
 		gtk_list_box_append (GTK_LIST_BOX (priv->input_list), widget);
 	}
 }
@@ -571,22 +589,23 @@
 update_ibus_active_sources (CcInputChooser *chooser)
 {
         CcInputChooserPrivate *priv;
+        gboolean invalidate = FALSE;
         IBusEngineDesc *engine_desc;
-        GtkWidget *child;
         const gchar *type;
         const gchar *id;
         gchar *name;
+        gsize i;
 
         priv = cc_input_chooser_get_instance_private (chooser);
-        child = gtk_widget_get_first_child (priv->input_list);
-        while (child) {
-                InputWidget *row;
 
-		row = get_input_widget (child);
-                child = gtk_widget_get_next_sibling (child);
+        for (i = 0; i < priv->input_widget_boxes->len; i++) {
+                GtkWidget *child;
+                InputWidget *row;
 
-		if (row == NULL)
-			continue;
+                child = g_ptr_array_index (priv->input_widget_boxes, i);
+                row = get_input_widget (child);
+                g_assert (row != NULL);
+                g_assert (row->box == child);
 
                 type = row->type;
                 id = row->id;
@@ -597,9 +616,16 @@
                 if (engine_desc) {
                         name = engine_get_display_name (engine_desc);
                         gtk_label_set_text (GTK_LABEL (row->label), name);
-                        g_free (name);
+                        g_clear_pointer (&row->name, g_free);
+                        row->name = g_steal_pointer (&name);
+                        invalidate = TRUE;
                 }
         }
+
+        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 void
@@ -758,6 +784,7 @@
 
 	g_clear_object (&priv->xkb_info);
 	g_hash_table_unref (priv->inputs);
+        g_clear_pointer (&priv->input_widget_boxes, g_ptr_array_unref);
 #ifdef HAVE_IBUS
         g_clear_object (&priv->ibus);
         if (priv->ibus_cancellable)
@@ -828,7 +855,10 @@
 static void
 cc_input_chooser_init (CcInputChooser *chooser)
 {
+        CcInputChooserPrivate *priv = cc_input_chooser_get_instance_private (chooser);
+
         gtk_widget_init_template (GTK_WIDGET (chooser));
+        priv->input_widget_boxes = g_ptr_array_new_with_free_func (g_object_unref);
 }
 
 void

Reply via email to