diff --git a/0001-keyboard-Get-default-input-sources-from-gnome-deskto.patch b/0001-keyboard-Get-default-input-sources-from-gnome-deskto.patch new file mode 100644 index 0000000..b1c5418 --- /dev/null +++ b/0001-keyboard-Get-default-input-sources-from-gnome-deskto.patch @@ -0,0 +1,628 @@ +From 02dbaf7ffc27804325573b6e2ccf732696c2a7f0 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 24 Aug 2023 21:19:40 -0400 +Subject: [PATCH 01/10] keyboard: Get default input sources from gnome-desktop + +Right now, we figure out the default input sources ourselves, +based on the current locale and layout information coming from +localed. + +This logic needs to be duplicated in several components, so its +now provided by gnome-desktop. + +This commit changes it over to use gnome-desktop APIs. + +The same time if leverages a gnome-desktop API to fix a bug +where cyrillic layouts were getting added without a latin +counterpart. +--- + .../pages/keyboard/gis-keyboard-page.c | 304 ++++++------------ + 1 file changed, 104 insertions(+), 200 deletions(-) + +diff --git a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c +index fa41230f..2583c447 100644 +--- a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c ++++ b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c +@@ -25,495 +25,399 @@ + #include "config.h" + + #include + #include + #include + #include + #include + + #define GNOME_DESKTOP_USE_UNSTABLE_API + #include + + #include "gis-keyboard-page.h" + #include "keyboard-resources.h" + #include "cc-input-chooser.h" + + #include "cc-common-language.h" + + #include "gis-page-header.h" + + #define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.gnome.desktop.input-sources" + #define KEY_CURRENT_INPUT_SOURCE "current" + #define KEY_INPUT_SOURCES "sources" + + struct _GisKeyboardPagePrivate { + GtkWidget *input_chooser; + + GDBusProxy *localed; + GCancellable *cancellable; + GPermission *permission; + GSettings *input_settings; ++ char **default_input_source_ids; ++ char **default_input_source_types; + +- GSList *system_sources; ++ gboolean should_skip; + }; + typedef struct _GisKeyboardPagePrivate GisKeyboardPagePrivate; + + G_DEFINE_TYPE_WITH_PRIVATE (GisKeyboardPage, gis_keyboard_page, GIS_TYPE_PAGE); + + static void + gis_keyboard_page_finalize (GObject *object) + { + GisKeyboardPage *self = GIS_KEYBOARD_PAGE (object); + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + + if (priv->cancellable) + g_cancellable_cancel (priv->cancellable); + g_clear_object (&priv->cancellable); + + g_clear_object (&priv->permission); + g_clear_object (&priv->localed); + g_clear_object (&priv->input_settings); +- +- g_slist_free_full (priv->system_sources, g_free); ++ g_clear_pointer (&priv->default_input_source_ids, g_strfreev); ++ g_clear_pointer (&priv->default_input_source_types, g_strfreev); + + G_OBJECT_CLASS (gis_keyboard_page_parent_class)->finalize (object); + } + + static void +-set_input_settings (GisKeyboardPage *self) ++set_input_settings (GisKeyboardPage *self, ++ const char *type, ++ const char *id) + { + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); +- const gchar *type; +- const gchar *id; ++ + GVariantBuilder builder; +- GSList *l; ++ size_t i; ++ gboolean has_latin_layout = FALSE; + gboolean is_xkb_source = FALSE; + +- type = cc_input_chooser_get_input_type (CC_INPUT_CHOOSER (priv->input_chooser)); +- id = cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)); +- + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); + +- if (g_str_equal (type, "xkb")) { +- g_variant_builder_add (&builder, "(ss)", type, id); +- is_xkb_source = TRUE; +- } ++ if (type != NULL && id != NULL) { ++ has_latin_layout = !gnome_input_source_is_non_latin (type, id); ++ if (g_str_equal (type, "xkb")) { ++ g_variant_builder_add (&builder, "(ss)", type, id); + +- for (l = priv->system_sources; l; l = l->next) { +- const gchar *sid = l->data; ++ is_xkb_source = TRUE; ++ } ++ } + +- if (g_str_equal (id, sid) && g_str_equal (type, "xkb")) ++ for (i = 0; priv->default_input_source_ids && priv->default_input_source_ids[i] != NULL; i++) { ++ if (g_str_equal (id, priv->default_input_source_ids[i]) && g_str_equal (type, priv->default_input_source_types[i])) + continue; + +- g_variant_builder_add (&builder, "(ss)", "xkb", sid); ++ g_variant_builder_add (&builder, "(ss)", priv->default_input_source_types[i], priv->default_input_source_ids[i]); ++ ++ if (!gnome_input_source_is_non_latin (priv->default_input_source_types[i], priv->default_input_source_ids[i])) ++ has_latin_layout = TRUE; + } + +- if (!is_xkb_source) +- g_variant_builder_add (&builder, "(ss)", type, id); ++ if (type != NULL && id != NULL) { ++ if (!is_xkb_source) { ++ g_variant_builder_add (&builder, "(ss)", type, id); ++ } ++ } + +- g_settings_set_value (priv->input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); +- g_settings_set_uint (priv->input_settings, KEY_CURRENT_INPUT_SOURCE, 0); ++ if (!has_latin_layout) { ++ g_variant_builder_add (&builder, "(ss)", "xkb", "us"); ++ } + +- g_settings_apply (priv->input_settings); ++ g_settings_set_value (priv->input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); ++ g_settings_set_uint (priv->input_settings, KEY_CURRENT_INPUT_SOURCE, 0); ++ g_settings_apply (priv->input_settings); + } + + static void + set_localed_input (GisKeyboardPage *self) + { + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + const gchar *layout, *variant; + GString *layouts; + GString *variants; +- GSList *l; ++ size_t i; + + if (!priv->localed) + return; + + cc_input_chooser_get_layout (CC_INPUT_CHOOSER (priv->input_chooser), &layout, &variant); + if (layout == NULL) + layout = ""; + if (variant == NULL) + variant = ""; + + layouts = g_string_new (layout); + variants = g_string_new (variant); + + #define LAYOUT(a) (a[0]) + #define VARIANT(a) (a[1] ? a[1] : "") +- for (l = priv->system_sources; l; l = l->next) { +- const gchar *sid = l->data; +- gchar **lv = g_strsplit (sid, "+", -1); ++ for (i = 0; priv->default_input_source_ids && priv->default_input_source_ids[i] != NULL; i++) { ++ const gchar *sid = priv->default_input_source_ids[i]; ++ g_auto (GStrv) lv = NULL; ++ ++ if (!g_str_equal (priv->default_input_source_types[i], "xkb")) ++ continue; ++ ++ lv = g_strsplit (sid, "+", -1); + + if (!g_str_equal (LAYOUT (lv), layout) || + !g_str_equal (VARIANT (lv), variant)) { + if (layouts->str[0]) { + g_string_append_c (layouts, ','); + g_string_append_c (variants, ','); + } + g_string_append (layouts, LAYOUT (lv)); + g_string_append (variants, VARIANT (lv)); + } +- g_strfreev (lv); + } + #undef LAYOUT + #undef VARIANT + + g_dbus_proxy_call (priv->localed, + "SetX11Keyboard", + g_variant_new ("(ssssbb)", layouts->str, "", variants->str, "", TRUE, TRUE), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); + g_string_free (layouts, TRUE); + g_string_free (variants, TRUE); + } + + static void + change_locale_permission_acquired (GObject *source, + GAsyncResult *res, + gpointer data) + { + GisKeyboardPage *page = GIS_KEYBOARD_PAGE (data); + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (page); + GError *error = NULL; + gboolean allowed; + + allowed = g_permission_acquire_finish (priv->permission, res, &error); + if (error) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to acquire permission: %s", error->message); + g_error_free (error); + return; + } + + if (allowed) + set_localed_input (GIS_KEYBOARD_PAGE (data)); + } + + static void + update_input (GisKeyboardPage *self) + { + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); ++ const gchar *type; ++ const gchar *id; ++ ++ type = cc_input_chooser_get_input_type (CC_INPUT_CHOOSER (priv->input_chooser)); ++ id = cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)); + +- set_input_settings (self); ++ set_input_settings (self, type, id); + + if (gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER) { + if (g_permission_get_allowed (priv->permission)) { + set_localed_input (self); + } else if (g_permission_get_can_acquire (priv->permission)) { + g_permission_acquire_async (priv->permission, + NULL, + change_locale_permission_acquired, + self); + } + } + } + + static gboolean + gis_keyboard_page_apply (GisPage *page, + GCancellable *cancellable) + { + update_input (GIS_KEYBOARD_PAGE (page)); + return FALSE; + } + +-static GSList * +-get_localed_input (GDBusProxy *proxy) +-{ +- GVariant *v; +- const gchar *s; +- gchar *id; +- guint i, n; +- gchar **layouts = NULL; +- gchar **variants = NULL; +- GSList *sources = NULL; +- +- v = g_dbus_proxy_get_cached_property (proxy, "X11Layout"); +- if (v) { +- s = g_variant_get_string (v, NULL); +- layouts = g_strsplit (s, ",", -1); +- g_variant_unref (v); +- } +- +- v = g_dbus_proxy_get_cached_property (proxy, "X11Variant"); +- if (v) { +- s = g_variant_get_string (v, NULL); +- if (s && *s) +- variants = g_strsplit (s, ",", -1); +- g_variant_unref (v); +- } +- +- if (variants && variants[0]) +- n = MIN (g_strv_length (layouts), g_strv_length (variants)); +- else if (layouts && layouts[0]) +- n = g_strv_length (layouts); +- else +- n = 0; +- +- for (i = 0; i < n && layouts[i][0]; i++) { +- if (variants && variants[i] && variants[i][0]) +- id = g_strdup_printf ("%s+%s", layouts[i], variants[i]); +- else +- id = g_strdup (layouts[i]); +- sources = g_slist_prepend (sources, id); +- } +- +- g_strfreev (variants); +- g_strfreev (layouts); +- +- return sources; +-} +- +-static void +-add_default_keyboard_layout (GDBusProxy *proxy, +- GVariantBuilder *builder) +-{ +- GSList *sources = get_localed_input (proxy); +- sources = g_slist_reverse (sources); +- +- for (; sources; sources = sources->next) +- g_variant_builder_add (builder, "(ss)", "xkb", +- (const gchar *) sources->data); +- +- g_slist_free_full (sources, g_free); +-} +- + static void +-add_default_input_sources (GisKeyboardPage *self, +- GDBusProxy *proxy) ++add_default_input_sources (GisKeyboardPage *self) + { +- const gchar *type; +- const gchar *id; +- gchar *language; ++ GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + GVariantBuilder builder; +- GSettings *input_settings; ++ gboolean defaults_have_latin = FALSE; ++ size_t i; + +- input_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); + +- add_default_keyboard_layout (proxy, &builder); +- +- /* add other input sources */ +- language = cc_common_language_get_current_language (); +- if (gnome_get_input_source_from_locale (language, &type, &id)) { +- if (!g_str_equal (type, "xkb")) +- g_variant_builder_add (&builder, "(ss)", type, id); ++ for (i = 0; priv->default_input_source_ids[i] != NULL; i++) { ++ g_variant_builder_add (&builder, "(ss)", priv->default_input_source_types[i], priv->default_input_source_ids[i]); ++ if (!gnome_input_source_is_non_latin (priv->default_input_source_types[i], priv->default_input_source_ids[i])) ++ defaults_have_latin = TRUE; + } +- g_free (language); + +- g_settings_delay (input_settings); +- g_settings_set_value (input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); +- g_settings_set_uint (input_settings, KEY_CURRENT_INPUT_SOURCE, 0); +- g_settings_apply (input_settings); +- +- g_object_unref (input_settings); +-} +- +-static void +-skip_proxy_ready (GObject *source, +- GAsyncResult *res, +- gpointer data) +-{ +- GisKeyboardPage *self = data; +- GDBusProxy *proxy; +- GError *error = NULL; +- +- proxy = g_dbus_proxy_new_finish (res, &error); +- +- if (!proxy) { +- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) +- g_warning ("Failed to contact localed: %s", error->message); +- g_error_free (error); +- return; +- } +- +- add_default_input_sources (self, proxy); ++ if (!defaults_have_latin) { ++ g_variant_builder_add (&builder, "(ss)", "xkb", "us"); ++ } + +- g_object_unref (proxy); ++ g_settings_set_value (priv->input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); ++ g_settings_set_uint (priv->input_settings, KEY_CURRENT_INPUT_SOURCE, 0); ++ g_settings_apply (priv->input_settings); + } + + static void + gis_keyboard_page_skip (GisPage *page) + { + GisKeyboardPage *self = GIS_KEYBOARD_PAGE (page); + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + +- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, +- G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, +- NULL, +- "org.freedesktop.locale1", +- "/org/freedesktop/locale1", +- "org.freedesktop.locale1", +- priv->cancellable, +- (GAsyncReadyCallback) skip_proxy_ready, +- self); ++ priv->should_skip = TRUE; ++ ++ if (priv->default_input_source_ids != NULL) ++ add_default_input_sources (self); + } + + static void + preselect_input_source (GisKeyboardPage *self) + { +- const gchar *type; +- const gchar *id; +- gchar *language; +- gboolean desktop_got_something; +- gboolean desktop_got_input_method; +- + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); +- GSList *sources = get_localed_input (priv->localed); +- +- /* These will be added silently after the user selection when +- * writing out the settings. */ +- g_slist_free_full (priv->system_sources, g_free); +- priv->system_sources = g_slist_reverse (sources); +- +- /* We have two potential sources of information as to which +- * source to pre-select here: the keyboard layout that is +- * configured system-wide (read from priv->system_sources), +- * and a gnome-desktop function that lets us look up a default +- * input source for a given language. +- * +- * An important limitation here is that there is no system-wide +- * configuration for input methods, so if the best choice for the +- * language is an input method, we will only find it from the +- * gnome-desktop lookup. But if both sources give us keyboard layouts, +- * we want to prefer the one that's configured system-wide over the one +- * from gnome-desktop. +- * +- * So we first do the gnome-desktop lookup, and keep track of what we +- * got. +- * +- * - If we got an input method, we preselect that, and we're done. +- * - If we got a keyboard layout, and there's no system-wide keyboard +- * layout set, we preselect the layout we got from gnome-desktop. +- * - If we didn't get an input method from gnome-desktop and there +- * is a system-wide keyboard layout set, we preselect that. +- * - If we got nothing from gnome-desktop and there's no system-wide +- * keyboard layout set, we don't preselect anything. +- * +- * See: +- * - https://bugzilla.gnome.org/show_bug.cgi?id=776189 +- * - https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/104 +- */ +- language = cc_common_language_get_current_language (); +- +- desktop_got_something = gnome_get_input_source_from_locale (language, &type, &id); +- desktop_got_input_method = (desktop_got_something && g_strcmp0 (type, "xkb") != 0); +- +- if (desktop_got_something && (desktop_got_input_method || !priv->system_sources)) { +- cc_input_chooser_set_input (CC_INPUT_CHOOSER (priv->input_chooser), +- id, type); +- } else if (priv->system_sources) { +- cc_input_chooser_set_input (CC_INPUT_CHOOSER (priv->input_chooser), +- (const gchar *) priv->system_sources->data, +- "xkb"); +- } + +- g_free (language); ++ cc_input_chooser_set_input (CC_INPUT_CHOOSER (priv->input_chooser), ++ priv->default_input_source_ids[0], ++ priv->default_input_source_types[0]); + } + + static void + update_page_complete (GisKeyboardPage *self) + { + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + gboolean complete; + + complete = (priv->localed != NULL && + cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)) != NULL); + gis_page_set_complete (GIS_PAGE (self), complete); + } + + static void + localed_proxy_ready (GObject *source, + GAsyncResult *res, + gpointer data) + { + GisKeyboardPage *self = data; + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + GDBusProxy *proxy; + GError *error = NULL; + + proxy = g_dbus_proxy_new_finish (res, &error); + + if (!proxy) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to contact localed: %s", error->message); + g_error_free (error); + return; + } + + priv->localed = proxy; +- +- preselect_input_source (self); +- update_page_complete (self); + } + + static void + input_confirmed (CcInputChooser *chooser, + GisKeyboardPage *self) + { + gis_assistant_next_page (gis_driver_get_assistant (GIS_PAGE (self)->driver)); + } + + static void + input_changed (CcInputChooser *chooser, + GisKeyboardPage *self) + { + update_page_complete (self); + } + ++static void ++on_got_default_sources (GObject *source, ++ GAsyncResult *res, ++ gpointer data) ++{ ++ GisKeyboardPage *self = data; ++ GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); ++ g_autoptr (GError) error = NULL; ++ g_auto (GStrv) ids = NULL; ++ g_auto (GStrv) types = NULL; ++ ++ ids = gnome_get_default_input_sources_finish (res, &types, &error); ++ ++ if (!ids) { ++ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ g_warning ("Failed to fetch default input sources: %s", error->message); ++ return; ++ } ++ ++ priv->default_input_source_ids = g_steal_pointer (&ids); ++ priv->default_input_source_types = g_steal_pointer (&types); ++ ++ if (priv->should_skip) { ++ add_default_input_sources (self); ++ return; ++ } ++ ++ preselect_input_source (self); ++ update_page_complete (self); ++} ++ + static void + gis_keyboard_page_constructed (GObject *object) + { + GisKeyboardPage *self = GIS_KEYBOARD_PAGE (object); + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + + G_OBJECT_CLASS (gis_keyboard_page_parent_class)->constructed (object); + + g_signal_connect (priv->input_chooser, "confirm", + G_CALLBACK (input_confirmed), self); + g_signal_connect (priv->input_chooser, "changed", + G_CALLBACK (input_changed), self); + + priv->input_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR); + g_settings_delay (priv->input_settings); + + priv->cancellable = g_cancellable_new (); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + NULL, + "org.freedesktop.locale1", + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + priv->cancellable, + (GAsyncReadyCallback) localed_proxy_ready, + self); + ++ gnome_get_default_input_sources (priv->cancellable, on_got_default_sources, self); ++ + /* If we're in new user mode then we're manipulating system settings */ + if (gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER) + priv->permission = polkit_permission_new_sync ("org.freedesktop.locale1.set-keyboard", NULL, NULL, NULL); + + update_page_complete (self); + + gtk_widget_set_visible (GTK_WIDGET (self), TRUE); + } + + static void + gis_keyboard_page_locale_changed (GisPage *page) + { + gis_page_set_title (GIS_PAGE (page), _("Typing")); + } + + static void + gis_keyboard_page_class_init (GisKeyboardPageClass * klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GisPageClass * page_class = GIS_PAGE_CLASS (klass); + + gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-keyboard-page.ui"); + + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisKeyboardPage, input_chooser); + + page_class->page_id = PAGE_ID; + page_class->apply = gis_keyboard_page_apply; + page_class->skip = gis_keyboard_page_skip; + page_class->locale_changed = gis_keyboard_page_locale_changed; + object_class->constructed = gis_keyboard_page_constructed; +-- +2.41.0.rc2 + diff --git a/0001-gnome-initial-setup-Bump-GLib-required-version-to-2..patch b/0002-gnome-initial-setup-Bump-GLib-required-version-to-2..patch similarity index 97% rename from 0001-gnome-initial-setup-Bump-GLib-required-version-to-2..patch rename to 0002-gnome-initial-setup-Bump-GLib-required-version-to-2..patch index 611a7b7..27db773 100644 --- a/0001-gnome-initial-setup-Bump-GLib-required-version-to-2..patch +++ b/0002-gnome-initial-setup-Bump-GLib-required-version-to-2..patch @@ -1,7 +1,7 @@ -From 58251548ef5835d1c1ce464fd4e8c29d99c1b343 Mon Sep 17 00:00:00 2001 +From 5efa8fe5b0abbe7cb951f0581a5511c0d682f290 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 15 Aug 2023 10:53:41 -0400 -Subject: [PATCH 1/7] gnome-initial-setup: Bump GLib required version to 2.70 +Subject: [PATCH 02/10] gnome-initial-setup: Bump GLib required version to 2.70 This gives us GStrvBuilder --- diff --git a/0002-driver-Specify-mode-via-flags-instead-of-boolean.patch b/0003-driver-Specify-mode-via-flags-instead-of-boolean.patch similarity index 99% rename from 0002-driver-Specify-mode-via-flags-instead-of-boolean.patch rename to 0003-driver-Specify-mode-via-flags-instead-of-boolean.patch index 3be92af..3e7a43f 100644 --- a/0002-driver-Specify-mode-via-flags-instead-of-boolean.patch +++ b/0003-driver-Specify-mode-via-flags-instead-of-boolean.patch @@ -1,7 +1,7 @@ -From 73d90588a4ab47d46c7aca4fe2f1313a1f7b1353 Mon Sep 17 00:00:00 2001 +From b511ec8b34d3120fc4a9dbf2202f40f335a2802f Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 13 Aug 2023 09:09:56 -0400 -Subject: [PATCH 2/7] driver: Specify mode via flags instead of boolean +Subject: [PATCH 03/10] driver: Specify mode via flags instead of boolean At the moment we just have system mode and new user mode, but we're actually going to want other modes (such as diff --git a/0004-initial-setup-Don-t-show-duplicated-pages-between-mo.patch b/0004-initial-setup-Don-t-show-duplicated-pages-between-mo.patch index 310fc8a..769be69 100644 --- a/0004-initial-setup-Don-t-show-duplicated-pages-between-mo.patch +++ b/0004-initial-setup-Don-t-show-duplicated-pages-between-mo.patch @@ -1,7 +1,8 @@ -From c03f853333a5c5ddb4d3549b7aa34a474b1aed42 Mon Sep 17 00:00:00 2001 +From dc25c47c1300e6b31dd0c9d5723f026a23e57ac3 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 16 Aug 2023 10:47:13 -0400 -Subject: [PATCH 4/7] initial-setup: Don't show duplicated pages between modes +Subject: [PATCH 04/10] initial-setup: Don't show duplicated pages between + modes It's possible a user just got asked questions in live mode before install that they'll then get asked again on first @@ -57,10 +58,10 @@ index 6a4ef7df..0bfccf56 100644 + strip_directory : true +) diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c -index b18a3808..41cd6e38 100644 +index d3013063..98fe2ca6 100644 --- a/gnome-initial-setup/gis-driver.c +++ b/gnome-initial-setup/gis-driver.c -@@ -80,90 +80,93 @@ struct _GisDriver { +@@ -78,90 +78,93 @@ struct _GisDriver { GtkWindow *main_window; GisAssistant *assistant; @@ -155,10 +156,12 @@ index b18a3808..41cd6e38 100644 gtk_window_set_child (GTK_WINDOW (driver->main_window), sw); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child); diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c -index bc7a4ee9..78c62cd8 100644 +index 59955779..49e8e6ca 100644 --- a/gnome-initial-setup/gnome-initial-setup.c +++ b/gnome-initial-setup/gnome-initial-setup.c -@@ -22,60 +22,62 @@ +@@ -20,60 +20,62 @@ + */ + #include "config.h" #include "gnome-initial-setup.h" @@ -181,18 +184,15 @@ index bc7a4ee9..78c62cd8 100644 #include "pages/parental-controls/gis-parental-controls-page.h" #include "pages/password/gis-password-page.h" #include "pages/summary/gis-summary-page.h" - #include "pages/install/gis-install-page.h" #define VENDOR_PAGES_GROUP "pages" #define VENDOR_SKIP_KEY "skip" #define VENDOR_NEW_USER_ONLY_KEY "new_user_only" #define VENDOR_EXISTING_USER_ONLY_KEY "existing_user_only" - #define VENDOR_LIVE_USER_ONLY_KEY "live_user_only" +#define STATE_FILE GIS_WORKING_DIR "/state" + static gboolean force_existing_user_mode; - static gboolean force_live_user_mode; static GPtrArray *skipped_pages; @@ -210,18 +210,19 @@ index bc7a4ee9..78c62cd8 100644 PAGE (welcome, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER), PAGE (language, GIS_DRIVER_MODE_ALL), PAGE (keyboard, GIS_DRIVER_MODE_ALL), - PAGE (network, GIS_DRIVER_MODE_ALL), + PAGE (network, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER), PAGE (privacy, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER), - PAGE (timezone, GIS_DRIVER_MODE_ALL), + PAGE (timezone, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER), PAGE (software, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER), PAGE (goa, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER), - /* In live user mode, the account page isn't displayed, it just quietly creates the live user */ - PAGE (account, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_LIVE_USER), - PAGE (password, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_LIVE_USER), + PAGE (account, GIS_DRIVER_MODE_NEW_USER), + PAGE (password, GIS_DRIVER_MODE_NEW_USER), #ifdef HAVE_PARENTAL_CONTROLS PAGE (parental_controls, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER), PAGE (parent_password, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER), -@@ -94,60 +96,61 @@ should_skip_page (const gchar *page_id, + #endif + PAGE (summary, GIS_DRIVER_MODE_NEW_USER), +@@ -89,60 +91,61 @@ should_skip_page (const gchar *page_id, guint i = 0; /* special case welcome. We only want to show it if language @@ -257,8 +258,8 @@ index bc7a4ee9..78c62cd8 100644 /* This code will read the keyfile containing vendor customization options and * look for options under the "pages" group, and supports the following keys: * - skip (optional): list of pages to be skipped always - * - new_user_only (optional): list of pages to be skipped for modes other than new_user - * - existing_user_only (optional): list of pages to be skipped for modes other than existing_user + * - new_user_only (optional): list of pages to be skipped in existing user mode + * - existing_user_only (optional): list of pages to be skipped in new user mode * * In addition it will look for options under the "{mode} pages" group where {mode} is the * current driver mode for the following keys: @@ -283,7 +284,7 @@ index bc7a4ee9..78c62cd8 100644 VENDOR_SKIP_KEY, NULL); if (skip_pages != NULL) { -@@ -162,60 +165,80 @@ pages_to_skip_from_file (GisDriver *driver) +@@ -157,60 +160,80 @@ pages_to_skip_from_file (GisDriver *driver) mode_group = g_strdup_printf ("%s pages", driver_mode_flags->value_nick); skip_pages = gis_driver_conf_get_string_list (driver, mode_group, @@ -364,7 +365,7 @@ index bc7a4ee9..78c62cd8 100644 page = data; assistant = gtk_widget_get_ancestor (GTK_WIDGET (page), GIS_TYPE_ASSISTANT); -@@ -371,59 +394,97 @@ main (int argc, char *argv[]) +@@ -359,59 +382,97 @@ main (int argc, char *argv[]) * it does in new-user mode, disable Initial Setup for existing users. * * https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/120#note_1019004 diff --git a/0005-keyboard-Don-t-add-default-input-sources-if-input-so.patch b/0005-keyboard-Don-t-add-default-input-sources-if-input-so.patch deleted file mode 100644 index ffc1a55..0000000 --- a/0005-keyboard-Don-t-add-default-input-sources-if-input-so.patch +++ /dev/null @@ -1,96 +0,0 @@ -From b06e6e46b11e8e3ad16212d05ae24c3ff3184a3c Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Sat, 19 Aug 2023 15:31:03 -0400 -Subject: [PATCH 5/7] keyboard: Don't add default input sources if input - sources already set - -If the keyboard page gets skipped, it adds default input sources derived -from the users locale. - -That is all fine and good, but may stomp on existiing site or distro configuration. - -This commit checks for that kind of thing first, and skips adding the -default in that case. ---- - gnome-initial-setup/pages/keyboard/gis-keyboard-page.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c -index e5556483..2448cf2f 100644 ---- a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c -+++ b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c -@@ -258,62 +258,71 @@ get_localed_input (GDBusProxy *proxy) - - g_strfreev (variants); - g_strfreev (layouts); - - return sources; - } - - static void - add_default_keyboard_layout (GDBusProxy *proxy, - GVariantBuilder *builder) - { - GSList *sources = get_localed_input (proxy); - sources = g_slist_reverse (sources); - - for (; sources; sources = sources->next) - g_variant_builder_add (builder, "(ss)", "xkb", - (const gchar *) sources->data); - - g_slist_free_full (sources, g_free); - } - - static void - add_default_input_sources (GisKeyboardPage *self, - GDBusProxy *proxy) - { - const gchar *type; - const gchar *id; - gchar *language; - GVariantBuilder builder; - GSettings *input_settings; -+ g_autoptr(GVariant) default_value = NULL; -+ g_autoptr(GVariant) value = NULL; - - input_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR); -+ -+ default_value = g_settings_get_default_value (input_settings, KEY_INPUT_SOURCES); -+ value = g_settings_get_value (input_settings, KEY_INPUT_SOURCES); -+ -+ if (!g_variant_equal (default_value, value)) -+ return; -+ - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); - - add_default_keyboard_layout (proxy, &builder); - - /* add other input sources */ - language = cc_common_language_get_current_language (); - if (gnome_get_input_source_from_locale (language, &type, &id)) { - if (!g_str_equal (type, "xkb")) - g_variant_builder_add (&builder, "(ss)", type, id); - } - g_free (language); - - g_settings_delay (input_settings); - g_settings_set_value (input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); - g_settings_set_uint (input_settings, KEY_CURRENT_INPUT_SOURCE, 0); - g_settings_apply (input_settings); - - g_object_unref (input_settings); - } - - static void - skip_proxy_ready (GObject *source, - GAsyncResult *res, - gpointer data) - { - GisKeyboardPage *self = data; - GDBusProxy *proxy; - GError *error = NULL; - - proxy = g_dbus_proxy_new_finish (res, &error); --- -2.41.0.rc2 - diff --git a/0005-summary-Write-uid-file-with-other-state-files.patch b/0005-summary-Write-uid-file-with-other-state-files.patch new file mode 100644 index 0000000..2b3319f --- /dev/null +++ b/0005-summary-Write-uid-file-with-other-state-files.patch @@ -0,0 +1,241 @@ +From 42d8bdfc0d37460cedf6fb3fe59bdfc0769c48ec Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 25 Aug 2023 21:30:42 -0400 +Subject: [PATCH 05/10] summary: Write uid file with other state files + +When creating a user account gnome-initial-setup writes a file +saying what the uid of the new user is, so that GDM can make +gnome-initial-setup's configuration available to the user. + +It does this from the summary page, but it would be better to do +it more centrally along with other state files so it can be used +for modes that don't have the summary page. + +This is important groundwork for a "live user" mode that will +get added in a future commit. +--- + gnome-initial-setup/gnome-initial-setup.c | 37 +++++++++++++++++++ + .../pages/summary/gis-summary-page.c | 24 ------------ + 2 files changed, 37 insertions(+), 24 deletions(-) + +diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c +index 49e8e6ca..3635f293 100644 +--- a/gnome-initial-setup/gnome-initial-setup.c ++++ b/gnome-initial-setup/gnome-initial-setup.c +@@ -418,61 +418,98 @@ write_state (GisDriver *driver) + g_auto(GStrv) visited_pages = NULL; + GisAssistant *assistant; + GList *pages, *node; + + state = g_key_file_new (); + + builder = g_strv_builder_new (); + + assistant = gis_driver_get_assistant (driver); + pages = gis_assistant_get_all_pages (assistant); + for (node = pages; node != NULL; node = node->next) { + GisPage *page = node->data; + g_strv_builder_add (builder, GIS_PAGE_GET_CLASS (page)->page_id); + } + + visited_pages = g_strv_builder_end (builder); + + g_key_file_set_string_list (state, + VENDOR_PAGES_GROUP, + VENDOR_SKIP_KEY, + (const char * const *) + visited_pages, + g_strv_length (visited_pages)); + + if (!g_key_file_save_to_file (state, STATE_FILE, &error)) { + g_warning ("Unable to save state to %s: %s", STATE_FILE, error->message); + return; + } + } + ++static void ++add_uid_file (GisDriver *driver) ++{ ++ gchar *gis_uid_path; ++ gchar *uid_str; ++ uid_t uid; ++ g_autoptr(GError) error = NULL; ++ ActUser *user_account = NULL; ++ ++ gis_driver_get_user_permissions (driver, &user_account, NULL); ++ ++ if (user_account == NULL) ++ return; ++ ++ uid = act_user_get_uid (user_account); ++ ++ gis_uid_path = g_build_filename (g_get_home_dir (), ++ "gnome-initial-setup-uid", ++ NULL); ++ uid_str = g_strdup_printf ("%u", uid); ++ ++ if (!g_file_set_contents (gis_uid_path, uid_str, -1, &error)) ++ g_warning ("Unable to create %s: %s", gis_uid_path, error->message); ++ ++ g_free (uid_str); ++ g_free (gis_uid_path); ++} ++ + void + gis_ensure_stamp_files (GisDriver *driver) + { + g_autofree gchar *done_file = NULL; + g_autoptr(GError) error = NULL; ++ GisDriverMode driver_mode; + + done_file = g_build_filename (g_get_user_config_dir (), "gnome-initial-setup-done", NULL); + if (!g_file_set_contents (done_file, "yes", -1, &error)) { + g_warning ("Unable to create %s: %s", done_file, error->message); + g_clear_error (&error); + } + ++ driver_mode = gis_driver_get_mode (driver); ++ ++ /* If we're in a system mode write out which UID the created user is so GDM can make the ++ * gnome-initial-setup home directory readable to the created user. ++ */ ++ if (driver_mode & GIS_DRIVER_MODE_SYSTEM) ++ add_uid_file (driver); ++ + write_state (driver); + } + + /** + * gis_get_mock_mode: + * + * Gets whether gnome-initial-setup has been built for development, and hence + * shouldn’t permanently change any system configuration. + * + * By default, mock mode is enabled when running in a build environment. This + * heuristic may be changed in future. + * + * Returns: %TRUE if in mock mode, %FALSE otherwise + */ + gboolean + gis_get_mock_mode (void) + { + return (g_getenv ("UNDER_JHBUILD") != NULL); + } +diff --git a/gnome-initial-setup/pages/summary/gis-summary-page.c b/gnome-initial-setup/pages/summary/gis-summary-page.c +index 0aee2dad..b072f7fc 100644 +--- a/gnome-initial-setup/pages/summary/gis-summary-page.c ++++ b/gnome-initial-setup/pages/summary/gis-summary-page.c +@@ -91,110 +91,86 @@ static void + on_secret_info_query (GdmUserVerifier *user_verifier, + const char *service_name, + const char *question, + GisSummaryPage *page) + { + GisSummaryPagePrivate *priv = gis_summary_page_get_instance_private (page); + gboolean should_send_password = priv->user_password != NULL; + + g_debug ("PAM module secret info query: %s", question); + if (should_send_password) { + g_debug ("sending password\n"); + gdm_user_verifier_call_answer_query (user_verifier, + service_name, + priv->user_password, + NULL, NULL, NULL); + priv->user_password = NULL; + } else { + request_info_query (page, user_verifier, question, TRUE); + } + } + + static void + on_session_opened (GdmGreeter *greeter, + const char *service_name, + GisSummaryPage *page) + { + gdm_greeter_call_start_session_when_ready_sync (greeter, service_name, + TRUE, NULL, NULL); + } + +-static void +-add_uid_file (uid_t uid) +-{ +- gchar *gis_uid_path; +- gchar *uid_str; +- g_autoptr(GError) error = NULL; +- +- gis_uid_path = g_build_filename (g_get_home_dir (), +- "gnome-initial-setup-uid", +- NULL); +- uid_str = g_strdup_printf ("%u", uid); +- +- if (!g_file_set_contents (gis_uid_path, uid_str, -1, &error)) +- g_warning ("Unable to create %s: %s", gis_uid_path, error->message); +- +- g_free (uid_str); +- g_free (gis_uid_path); +-} +- + static void + log_user_in (GisSummaryPage *page) + { + GisSummaryPagePrivate *priv = gis_summary_page_get_instance_private (page); + g_autoptr(GError) error = NULL; + GdmGreeter *greeter = NULL; + GdmUserVerifier *user_verifier = NULL; + + if (!gis_driver_get_gdm_objects (GIS_PAGE (page)->driver, + &greeter, &user_verifier)) { + g_warning ("No GDM connection; not initiating login"); + return; + } + + g_signal_connect (user_verifier, "info", + G_CALLBACK (on_info), page); + g_signal_connect (user_verifier, "problem", + G_CALLBACK (on_problem), page); + g_signal_connect (user_verifier, "info-query", + G_CALLBACK (on_info_query), page); + g_signal_connect (user_verifier, "secret-info-query", + G_CALLBACK (on_secret_info_query), page); + + g_signal_connect (greeter, "session-opened", + G_CALLBACK (on_session_opened), page); + +- /* We are in NEW_USER mode and we want to make it possible for third +- * parties to find out which user ID we created. +- */ +- add_uid_file (act_user_get_uid (priv->user_account)); +- + gdm_user_verifier_call_begin_verification_for_user_sync (user_verifier, + SERVICE_NAME, + act_user_get_user_name (priv->user_account), + NULL, &error); + + if (error != NULL) + g_warning ("Could not begin verification: %s", error->message); + } + + static void + done_cb (GtkButton *button, GisSummaryPage *page) + { + gis_ensure_stamp_files (GIS_PAGE (page)->driver); + + switch (gis_driver_get_mode (GIS_PAGE (page)->driver)) + { + case GIS_DRIVER_MODE_NEW_USER: + gis_driver_hide_window (GIS_PAGE (page)->driver); + log_user_in (page); + break; + case GIS_DRIVER_MODE_EXISTING_USER: + g_application_quit (G_APPLICATION (GIS_PAGE (page)->driver)); + default: + break; + } + } + + static void + gis_summary_page_shown (GisPage *page) + { +-- +2.41.0.rc2 + diff --git a/0003-gnome-initial-setup-Add-live-user-mode.patch b/0006-gnome-initial-setup-Add-live-user-mode.patch similarity index 97% rename from 0003-gnome-initial-setup-Add-live-user-mode.patch rename to 0006-gnome-initial-setup-Add-live-user-mode.patch index b33f9af..e266edd 100644 --- a/0003-gnome-initial-setup-Add-live-user-mode.patch +++ b/0006-gnome-initial-setup-Add-live-user-mode.patch @@ -1,7 +1,7 @@ -From bf02d8405e7192f736ecc7088f2bd265b87db4b7 Mon Sep 17 00:00:00 2001 +From a7112122b3f1c68ab96e644e4c62715f02d5af69 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 13 Aug 2023 09:39:07 -0400 -Subject: [PATCH 3/7] gnome-initial-setup: Add live user mode +Subject: [PATCH 06/10] gnome-initial-setup: Add live user mode This commit adds a new "live user" mode meant to be run in live image environments. @@ -70,7 +70,7 @@ index 02fd21d0..881efde9 100644 return undefined; }); diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c -index d3013063..b18a3808 100644 +index 98fe2ca6..41cd6e38 100644 --- a/gnome-initial-setup/gis-driver.c +++ b/gnome-initial-setup/gis-driver.c @@ -19,60 +19,62 @@ @@ -136,7 +136,7 @@ index d3013063..b18a3808 100644 struct _GisDriver { AdwApplication parent_instance; -@@ -764,61 +766,61 @@ static void +@@ -767,61 +769,61 @@ static void connect_to_gdm (GisDriver *driver) { g_autoptr(GError) error = NULL; @@ -400,10 +400,10 @@ index 5041bddd..10dcd70c 100644 +gboolean gis_kernel_command_line_has_argument (const char *arguments[]); +void gis_substitute_word_in_text (char **text, const char *old_word, const char *new_word); diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c -index 59955779..bc7a4ee9 100644 +index 3635f293..0e155cd3 100644 --- a/gnome-initial-setup/gnome-initial-setup.c +++ b/gnome-initial-setup/gnome-initial-setup.c -@@ -14,141 +14,146 @@ +@@ -14,144 +14,149 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . @@ -442,6 +442,8 @@ index 59955779..bc7a4ee9 100644 #define VENDOR_EXISTING_USER_ONLY_KEY "existing_user_only" +#define VENDOR_LIVE_USER_ONLY_KEY "live_user_only" + #define STATE_FILE GIS_WORKING_DIR "/state" + static gboolean force_existing_user_mode; +static gboolean force_live_user_mode; @@ -518,6 +520,7 @@ index 59955779..bc7a4ee9 100644 g_autofree char *mode_group = NULL; g_autoptr (GFlagsClass) driver_mode_flags_class = NULL; const GFlagsValue *driver_mode_flags = NULL; + g_autoptr (GError) error = NULL; /* This code will read the keyfile containing vendor customization options and * look for options under the "pages" group, and supports the following keys: @@ -556,7 +559,7 @@ index 59955779..bc7a4ee9 100644 driver_mode_flags_class = g_type_class_ref (GIS_TYPE_DRIVER_MODE); -@@ -250,130 +255,137 @@ rebuild_pages_cb (GisDriver *driver) +@@ -273,130 +278,137 @@ rebuild_pages_cb (GisDriver *driver) driver_mode = gis_driver_get_mode (driver); skip_pages = pages_to_skip_from_file (driver); @@ -1285,15 +1288,10 @@ index 00000000..e5084e5e + 'gis-install-page.h' +) diff --git a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c -index fa41230f..e5556483 100644 +index 2583c447..cb4f68d8 100644 --- a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c +++ b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c -@@ -168,61 +168,61 @@ set_localed_input (GisKeyboardPage *self) - - static void - change_locale_permission_acquired (GObject *source, - GAsyncResult *res, - gpointer data) +@@ -189,61 +189,61 @@ change_locale_permission_acquired (GObject *source, { GisKeyboardPage *page = GIS_KEYBOARD_PAGE (data); GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (page); @@ -1316,8 +1314,13 @@ index fa41230f..e5556483 100644 update_input (GisKeyboardPage *self) { GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + const gchar *type; + const gchar *id; - set_input_settings (self); + type = cc_input_chooser_get_input_type (CC_INPUT_CHOOSER (priv->input_chooser)); + id = cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)); + + set_input_settings (self, type, id); - if (gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER) { + if (gis_driver_get_mode (GIS_PAGE (self)->driver) & GIS_DRIVER_MODE_SYSTEM) { @@ -1340,20 +1343,18 @@ index fa41230f..e5556483 100644 return FALSE; } - static GSList * - get_localed_input (GDBusProxy *proxy) - { - GVariant *v; - const gchar *s; - gchar *id; - guint i, n; - gchar **layouts = NULL; - gchar **variants = NULL; - GSList *sources = NULL; - -@@ -461,61 +461,61 @@ input_changed (CcInputChooser *chooser, - static void + add_default_input_sources (GisKeyboardPage *self) + { + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + GVariantBuilder builder; + gboolean defaults_have_latin = FALSE; + size_t i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); + + for (i = 0; priv->default_input_source_ids[i] != NULL; i++) { +@@ -365,61 +365,61 @@ static void gis_keyboard_page_constructed (GObject *object) { GisKeyboardPage *self = GIS_KEYBOARD_PAGE (object); @@ -1381,6 +1382,8 @@ index fa41230f..e5556483 100644 (GAsyncReadyCallback) localed_proxy_ready, self); + gnome_get_default_input_sources (priv->cancellable, on_got_default_sources, self); + /* If we're in new user mode then we're manipulating system settings */ - if (gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER) + if (gis_driver_get_mode (GIS_PAGE (self)->driver) & GIS_DRIVER_MODE_SYSTEM) diff --git a/0007-keyboard-Don-t-add-default-input-sources-if-input-so.patch b/0007-keyboard-Don-t-add-default-input-sources-if-input-so.patch new file mode 100644 index 0000000..9feec5f --- /dev/null +++ b/0007-keyboard-Don-t-add-default-input-sources-if-input-so.patch @@ -0,0 +1,99 @@ +From 893ecb7194306ce1fb3637454849e3183a58f742 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sat, 19 Aug 2023 15:31:03 -0400 +Subject: [PATCH 07/10] keyboard: Don't add default input sources if input + sources already set + +If the keyboard page gets skipped, it adds default input sources derived +from the users locale. + +That is all fine and good, but may stomp on existiing site or distro configuration. + +This commit checks for that kind of thing first, and skips adding the +default in that case. +--- + .../pages/keyboard/gis-keyboard-page.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c +index cb4f68d8..febd1483 100644 +--- a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c ++++ b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c +@@ -214,63 +214,74 @@ update_input (GisKeyboardPage *self) + type = cc_input_chooser_get_input_type (CC_INPUT_CHOOSER (priv->input_chooser)); + id = cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)); + + set_input_settings (self, type, id); + + if (gis_driver_get_mode (GIS_PAGE (self)->driver) & GIS_DRIVER_MODE_SYSTEM) { + if (g_permission_get_allowed (priv->permission)) { + set_localed_input (self); + } else if (g_permission_get_can_acquire (priv->permission)) { + g_permission_acquire_async (priv->permission, + NULL, + change_locale_permission_acquired, + self); + } + } + } + + static gboolean + gis_keyboard_page_apply (GisPage *page, + GCancellable *cancellable) + { + update_input (GIS_KEYBOARD_PAGE (page)); + return FALSE; + } + + static void + add_default_input_sources (GisKeyboardPage *self) + { + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + GVariantBuilder builder; ++ GSettings *input_settings; ++ g_autoptr(GVariant) default_value = NULL; ++ g_autoptr(GVariant) value = NULL; + gboolean defaults_have_latin = FALSE; + size_t i; + ++ input_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR); ++ ++ default_value = g_settings_get_default_value (input_settings, KEY_INPUT_SOURCES); ++ value = g_settings_get_value (input_settings, KEY_INPUT_SOURCES); ++ ++ if (!g_variant_equal (default_value, value)) ++ return; ++ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); + + for (i = 0; priv->default_input_source_ids[i] != NULL; i++) { + g_variant_builder_add (&builder, "(ss)", priv->default_input_source_types[i], priv->default_input_source_ids[i]); + if (!gnome_input_source_is_non_latin (priv->default_input_source_types[i], priv->default_input_source_ids[i])) + defaults_have_latin = TRUE; + } + + if (!defaults_have_latin) { + g_variant_builder_add (&builder, "(ss)", "xkb", "us"); + } + + g_settings_set_value (priv->input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); + g_settings_set_uint (priv->input_settings, KEY_CURRENT_INPUT_SOURCE, 0); + g_settings_apply (priv->input_settings); + } + + static void + gis_keyboard_page_skip (GisPage *page) + { + GisKeyboardPage *self = GIS_KEYBOARD_PAGE (page); + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + + priv->should_skip = TRUE; + + if (priv->default_input_source_ids != NULL) + add_default_input_sources (self); + } + + static void +-- +2.41.0.rc2 + diff --git a/0006-gnome-initial-setup-Add-OEM-mode.patch b/0008-gnome-initial-setup-Add-OEM-mode.patch similarity index 98% rename from 0006-gnome-initial-setup-Add-OEM-mode.patch rename to 0008-gnome-initial-setup-Add-OEM-mode.patch index 078bb3c..4e2a889 100644 --- a/0006-gnome-initial-setup-Add-OEM-mode.patch +++ b/0008-gnome-initial-setup-Add-OEM-mode.patch @@ -1,7 +1,7 @@ -From 4f2aa7291f77b75efd7ec3a1a36371dc1a2bd7e9 Mon Sep 17 00:00:00 2001 +From 79e3d56cf0670854cb32e1884cb9c4e14664aad1 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 13 Aug 2023 10:30:11 -0400 -Subject: [PATCH 6/7] gnome-initial-setup: Add OEM mode +Subject: [PATCH 08/10] gnome-initial-setup: Add OEM mode OEM mode is designed to get run when a site has imaged a bunch of machines, and handed them off to the user. @@ -155,7 +155,7 @@ index aedb9a73..49639bef 100644 gboolean parental_controls_enabled); diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c -index 78c62cd8..d9e9ca6e 100644 +index 0e155cd3..82b8bba9 100644 --- a/gnome-initial-setup/gnome-initial-setup.c +++ b/gnome-initial-setup/gnome-initial-setup.c @@ -26,90 +26,91 @@ diff --git a/0007-polkit-Add-fedora-specfic-rules.patch b/0009-polkit-Add-fedora-specfic-rules.patch similarity index 94% rename from 0007-polkit-Add-fedora-specfic-rules.patch rename to 0009-polkit-Add-fedora-specfic-rules.patch index 60c1241..56a4d8a 100644 --- a/0007-polkit-Add-fedora-specfic-rules.patch +++ b/0009-polkit-Add-fedora-specfic-rules.patch @@ -1,7 +1,7 @@ -From 5551d61c2bef3b607b9cb2a3058d97ce5afc1c03 Mon Sep 17 00:00:00 2001 +From 58a26e35a2d367dd501faf8dcecac3569fab274d Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 13 Aug 2023 16:33:49 -0400 -Subject: [PATCH 7/7] polkit: Add fedora specfic rules +Subject: [PATCH 09/10] polkit: Add fedora specfic rules We should probably add some way to check vendor.conf for the policy updates instead of a hardcoded list. diff --git a/0010-gnome-initial-setup-Read-etc-sysconfig-anaconda.patch b/0010-gnome-initial-setup-Read-etc-sysconfig-anaconda.patch new file mode 100644 index 0000000..7bac10e --- /dev/null +++ b/0010-gnome-initial-setup-Read-etc-sysconfig-anaconda.patch @@ -0,0 +1,117 @@ +From 26543a5a3a9e54c88f72b6d4cd0fe019933765ae Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 22 Aug 2023 13:51:40 -0400 +Subject: [PATCH 10/10] gnome-initial-setup: Read /etc/sysconfig/anaconda + +Just as /var/lib/gnome-initial-setup/state may show pages the user has +already answered, on Fedora, /etc/sysconfig/anaconda shows pages the user has +already answered via Anaconda. + +This commit skips those from the --new-user mode as well. +--- + gnome-initial-setup/gnome-initial-setup.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c +index 82b8bba9..0ac93fe9 100644 +--- a/gnome-initial-setup/gnome-initial-setup.c ++++ b/gnome-initial-setup/gnome-initial-setup.c +@@ -172,72 +172,95 @@ pages_to_skip_from_file (GisDriver *driver) + g_strv_builder_addv (builder, (const char **) skip_pages); + g_clear_pointer (&skip_pages, g_strfreev); + } + + other_modes = GIS_DRIVER_MODE_ALL & ~driver_mode; + while (other_modes) { + const GFlagsValue *other_mode_flags = g_flags_get_first_value (driver_mode_flags_class, other_modes); + + if (other_mode_flags != NULL) { + g_autofree char *vendor_key = g_strdup_printf ("%s_only", other_mode_flags->value_nick); + + skip_pages = gis_driver_conf_get_string_list (driver, VENDOR_PAGES_GROUP, + vendor_key, NULL); + + if (skip_pages != NULL) + { + g_strv_builder_addv (builder, (const char **) skip_pages); + g_clear_pointer (&skip_pages, g_strfreev); + } + + other_modes &= ~other_mode_flags->value; + } + } + + /* Also, if this is a system mode, we check if the user already answered questions earlier in + * a different system mode, and skip those pages too. + */ + if (driver_mode & GIS_DRIVER_MODE_NEW_USER) { + g_autoptr(GKeyFile) state = NULL; + gboolean state_loaded; ++ g_autoptr(GKeyFile) anaconda = NULL; ++ gboolean anaconda_loaded; + + state = g_key_file_new (); + state_loaded = g_key_file_load_from_file (state, STATE_FILE, G_KEY_FILE_NONE, &error); + + if (state_loaded) { + skip_pages = g_key_file_get_string_list (state, VENDOR_PAGES_GROUP, VENDOR_SKIP_KEY, NULL, NULL); + + if (skip_pages != NULL) { + g_strv_builder_addv (builder, (const char **) skip_pages); + g_clear_pointer (&skip_pages, g_strfreev); + } + } ++ ++ anaconda = g_key_file_new (); ++ anaconda_loaded = g_key_file_load_from_file (anaconda, "/etc/sysconfig/anaconda", G_KEY_FILE_NONE, NULL); ++ ++ if (anaconda_loaded) { ++ struct { ++ const char *spoke_name; ++ const char *page_name; ++ } spoke_page_map[] = { ++ { "WelcomeLanguageSpoke", "language" }, ++ { "DatetimeSpoke", "timezone" }, ++ { "KeyboardSpoke", "keyboard" }, ++ { NULL, NULL } ++ }; ++ size_t i; ++ ++ for (i = 0; spoke_page_map[i].spoke_name != NULL; i++) { ++ if (g_key_file_get_boolean (anaconda, spoke_page_map[i].spoke_name, "visited", NULL)) ++ g_strv_builder_add (builder, spoke_page_map[i].page_name); ++ } ++ } + } + + return g_strv_builder_end (builder); + } + + static void + destroy_pages_after (GisAssistant *assistant, + GisPage *page) + { + GList *pages, *l, *next; + + pages = gis_assistant_get_all_pages (assistant); + + for (l = pages; l != NULL; l = l->next) + if (l->data == page) + break; + + l = l->next; + for (; l != NULL; l = next) { + next = l->next; + gis_assistant_remove_page (assistant, l->data); + } + } + + static void + destroy_page (gpointer data) + { + GtkWidget *assistant; + GisPage *page; + +-- +2.41.0.rc2 + diff --git a/gnome-initial-setup.spec b/gnome-initial-setup.spec index 0726d30..764809b 100644 --- a/gnome-initial-setup.spec +++ b/gnome-initial-setup.spec @@ -16,14 +16,16 @@ URL: https://wiki.gnome.org/Design/OS/InitialSetup Source0: https://download.gnome.org/sources/%{name}/45/%{name}-%{tarball_version}.tar.xz Source1: vendor.conf -Patch: 0001-gnome-initial-setup-Bump-GLib-required-version-to-2..patch -Patch: 0002-driver-Specify-mode-via-flags-instead-of-boolean.patch -Patch: 0003-gnome-initial-setup-Add-live-user-mode.patch +Patch: 0001-keyboard-Get-default-input-sources-from-gnome-deskto.patch +Patch: 0002-gnome-initial-setup-Bump-GLib-required-version-to-2..patch +Patch: 0003-driver-Specify-mode-via-flags-instead-of-boolean.patch Patch: 0004-initial-setup-Don-t-show-duplicated-pages-between-mo.patch -Patch: 0005-keyboard-Don-t-add-default-input-sources-if-input-so.patch -Patch: 0006-gnome-initial-setup-Add-OEM-mode.patch -Patch: 0007-polkit-Add-fedora-specfic-rules.patch - +Patch: 0005-summary-Write-uid-file-with-other-state-files.patch +Patch: 0006-gnome-initial-setup-Add-live-user-mode.patch +Patch: 0007-keyboard-Don-t-add-default-input-sources-if-input-so.patch +Patch: 0008-gnome-initial-setup-Add-OEM-mode.patch +Patch: 0009-polkit-Add-fedora-specfic-rules.patch +Patch: 0010-gnome-initial-setup-Read-etc-sysconfig-anaconda.patch BuildRequires: desktop-file-utils BuildRequires: gcc @@ -57,6 +59,7 @@ BuildRequires: pkgconfig(polkit-gobject-1) BuildRequires: pkgconfig(pwquality) BuildRequires: pkgconfig(rest-1.0) BuildRequires: pkgconfig(webkitgtk-6.0) +BuildRequires: gnome-desktop4 >= 44.0-5 # gnome-initial-setup is being run by gdm Requires: gdm @@ -94,7 +97,7 @@ cp %{SOURCE1} %{buildroot}%{_datadir}/gnome-initial-setup/ %find_lang %{name} %pre -useradd -rM -d %{_localstatedir}/lib/gnome-initial-setup/ -s /sbin/nologin %{name} &>/dev/null || : +useradd -rM -d /run/gnome-initial-setup/ -s /sbin/nologin %{name} &>/dev/null || : %files -f %{name}.lang %license COPYING