From 99f56c244ed41bb63e9873dbbadfbadaa7e24c15 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 8 Sep 2023 11:02:39 -0400 Subject: [PATCH 03/12] language: Don't proceed until localed has set locale In sysmte modes, the keyboard page requires reading the locale from localed, so we need to make sure the setting has been applied before proceeding to the keyboard page from the language page. This commit changes the Next button to desensitize if a set locale operation is pending. --- .../pages/language/gis-language-page.c | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/gnome-initial-setup/pages/language/gis-language-page.c b/gnome-initial-setup/pages/language/gis-language-page.c index 87b9f2d8..26a01257 100644 --- a/gnome-initial-setup/pages/language/gis-language-page.c +++ b/gnome-initial-setup/pages/language/gis-language-page.c @@ -29,181 +29,204 @@ #define GNOME_SYSTEM_LOCALE_DIR "org.gnome.system.locale" #define REGION_KEY "region" #include "config.h" #include "language-resources.h" #include "gis-welcome-widget.h" #include "cc-language-chooser.h" #include "gis-language-page.h" #include #include #include #include struct _GisLanguagePagePrivate { GtkWidget *logo; GtkWidget *welcome_widget; GtkWidget *language_chooser; GDBusProxy *localed; GPermission *permission; const gchar *new_locale_id; GCancellable *cancellable; }; typedef struct _GisLanguagePagePrivate GisLanguagePagePrivate; G_DEFINE_TYPE_WITH_PRIVATE (GisLanguagePage, gis_language_page, GIS_TYPE_PAGE); +static void +on_locale_set (GDBusProxy *proxy, + GAsyncResult *result, + GisLanguagePage *self) +{ + g_autoptr(GError) error = NULL; + g_autoptr(GVariant) call_result = NULL; + + call_result = g_dbus_proxy_call_finish (proxy, result, &error); + + if (error != NULL) { + g_warning ("Could not set system locale: %s", error->message); + } + + gis_page_set_complete (GIS_PAGE (self), TRUE); +} + static void set_localed_locale (GisLanguagePage *self) { GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (self); GVariantBuilder *b; gchar *s; b = g_variant_builder_new (G_VARIANT_TYPE ("as")); s = g_strconcat ("LANG=", priv->new_locale_id, NULL); g_variant_builder_add (b, "s", s); g_free (s); g_dbus_proxy_call (priv->localed, "SetLocale", g_variant_new ("(asb)", b, TRUE), G_DBUS_CALL_FLAGS_NONE, - -1, NULL, NULL, NULL); + -1, priv->cancellable, + (GAsyncReadyCallback) on_locale_set, + self); g_variant_builder_unref (b); } static void change_locale_permission_acquired (GObject *source, GAsyncResult *res, gpointer data) { GisLanguagePage *page = GIS_LANGUAGE_PAGE (data); GisLanguagePagePrivate *priv = gis_language_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_locale (page); } static void user_loaded (GObject *object, GParamSpec *pspec, gpointer user_data) { gchar *new_locale_id = user_data; act_user_set_language (ACT_USER (object), new_locale_id); g_free (new_locale_id); } static void language_changed (CcLanguageChooser *chooser, GParamSpec *pspec, GisLanguagePage *page) { GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page); GisDriver *driver; GSettings *region_settings; ActUser *user; priv->new_locale_id = cc_language_chooser_get_language (chooser); driver = GIS_PAGE (page)->driver; gis_driver_set_user_language (driver, priv->new_locale_id, TRUE); gtk_widget_set_default_direction (gtk_get_locale_direction ()); if (gis_driver_get_mode (driver) == GIS_DRIVER_MODE_NEW_USER) { + + gis_page_set_complete (GIS_PAGE (page), FALSE); + if (g_permission_get_allowed (priv->permission)) { set_localed_locale (page); } else if (g_permission_get_can_acquire (priv->permission)) { g_permission_acquire_async (priv->permission, NULL, change_locale_permission_acquired, page); } } /* Ensure we won't override the selected language for format strings */ region_settings = g_settings_new (GNOME_SYSTEM_LOCALE_DIR); g_settings_reset (region_settings, REGION_KEY); g_object_unref (region_settings); user = act_user_manager_get_user (act_user_manager_get_default (), g_get_user_name ()); if (act_user_is_loaded (user)) act_user_set_language (user, priv->new_locale_id); else g_signal_connect (user, "notify::is-loaded", G_CALLBACK (user_loaded), g_strdup (priv->new_locale_id)); gis_welcome_widget_show_locale (GIS_WELCOME_WIDGET (priv->welcome_widget), priv->new_locale_id); } static void localed_proxy_ready (GObject *source, GAsyncResult *res, gpointer data) { GisLanguagePage *self = data; GisLanguagePagePrivate *priv = gis_language_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; + gis_page_set_complete (GIS_PAGE (self), TRUE); } static void update_distro_logo (GisLanguagePage *page) { GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page); g_autofree char *id = g_get_os_info (G_OS_INFO_KEY_ID); gsize i; static const struct { const char *id; const char *logo; } id_to_logo[] = { { "debian", "emblem-debian" }, { "fedora", "fedora-logo-icon" }, { "ubuntu", "ubuntu-logo-icon" }, { "openSUSE Tumbleweed", "opensuse-logo-icon" }, { "openSUSE Leap", "opensuse-logo-icon" }, { "SLED", "suse-logo-icon" }, { "SLES", "suse-logo-icon" }, }; for (i = 0; i < G_N_ELEMENTS (id_to_logo); i++) { if (g_strcmp0 (id, id_to_logo[i].id) == 0) { g_object_set (priv->logo, "icon-name", id_to_logo[i].logo, NULL); break; } } @@ -224,62 +247,64 @@ gis_language_page_constructed (GObject *object) GDBusConnection *bus; g_type_ensure (CC_TYPE_LANGUAGE_CHOOSER); G_OBJECT_CLASS (gis_language_page_parent_class)->constructed (object); update_distro_logo (page); g_signal_connect (priv->language_chooser, "notify::language", G_CALLBACK (language_changed), page); g_signal_connect (priv->language_chooser, "confirm", G_CALLBACK (language_confirmed), page); /* If we're in new user mode then we're manipulating system settings */ if (gis_driver_get_mode (GIS_PAGE (page)->driver) == GIS_DRIVER_MODE_NEW_USER) { priv->permission = polkit_permission_new_sync ("org.freedesktop.locale1.set-locale", NULL, NULL, NULL); bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); g_dbus_proxy_new (bus, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, NULL, "org.freedesktop.locale1", "/org/freedesktop/locale1", "org.freedesktop.locale1", priv->cancellable, (GAsyncReadyCallback) localed_proxy_ready, object); g_object_unref (bus); } - - gis_page_set_complete (GIS_PAGE (page), TRUE); + else + { + gis_page_set_complete (GIS_PAGE (page), TRUE); + } gtk_widget_set_visible (GTK_WIDGET (page), TRUE); } static void gis_language_page_locale_changed (GisPage *page) { gis_page_set_title (GIS_PAGE (page), _("Welcome")); } static void gis_language_page_dispose (GObject *object) { GisLanguagePage *page = GIS_LANGUAGE_PAGE (object); GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page); g_clear_object (&priv->permission); g_clear_object (&priv->localed); g_clear_object (&priv->cancellable); G_OBJECT_CLASS (gis_language_page_parent_class)->dispose (object); } static void gis_language_page_class_init (GisLanguagePageClass *klass) { GisPageClass *page_class = GIS_PAGE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-language-page.ui"); -- 2.41.0