summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Thompson <wjt@endlessos.org>2023-02-26 21:45:16 +0000
committerWill Thompson <wjt@endlessos.org>2023-02-27 13:15:49 +0000
commit3cc1e280a0fb30dc7faa43d6541f0c535ca49cd0 (patch)
tree7d2ca4b696ed2e70fbdeb20e0d39f5b550a7f433
parentd42fefe06e4e0f4b4bcf5b5dbdf5c9d3b3eca79b (diff)
downloadgnome-initial-setup-3cc1e280a0fb30dc7faa43d6541f0c535ca49cd0.tar.gz
driver: Set all categories when changing locale
Previously, Initial Setup would only change the LC_MESSAGES locale category when the user selects a different locale on the language page. However, this caused non-ASCII characters to be mangled after switching locale. The following test program demonstrates the problem: #include "config.h" #include <locale.h> #include <glib.h> #include <glib/gi18n-lib.h> #include <libgweather/gweather.h> gint main (gint argc, gchar *argv[]) { /* gettext boilerplate */ setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); /* Change locale to Czech */ locale_t locale = newlocale (LC_MESSAGES_MASK, "cs_CZ.utf8", (locale_t) 0); g_assert (locale != (locale_t) 0); uselocale (locale); GWeatherLocation *world = gweather_location_get_world (); GWeatherLocation *praha = gweather_location_find_nearest_city (world, 50.08804, 14.42076); g_message ("%s", gweather_location_get_name (gweather_location_get_parent (praha))); return 0; } The desired output is “Česká republika”, but this program instead prints “?esk? republika”. The non-ASCII characters with diacritics are mangled. The same problem exists in any locale: switch to an English locale in this way, then search for “Abidjan”; it will be reported to be in “C?te d’Ivoire”. The issue appears to be that the LC_CTYPE category is not being changed. According to locale(7): > This category determines the interpretation of byte sequences as > characters (e.g., single versus multibyte characters), character > classifications (e.g., alphabetic or digit), and the behavior of > character classes. Rather than adding this category, just set all categories. It's true that Initial Setup doesn't use, for instance, anything related to the locale's measurement system (LC_MEASUREMENT, i.e. metric versus US customary units) but it should be harmless to set them all. The change in cc-common-language is probably unnecessary. insert_language() is checking that the given locale actually exists on the system before offering it to the user. Surely if newlocale(LC_MESSAGES_MASK, x, 0) works then newlocale(LC_ALL_MASK, x, 0) will work? But there is no harm in using LC_ALL_MASK and the consistency is clearer. Fixes #177
-rw-r--r--gnome-initial-setup/cc-common-language.c2
-rw-r--r--gnome-initial-setup/gis-driver.c2
2 files changed, 2 insertions, 2 deletions
diff --git a/gnome-initial-setup/cc-common-language.c b/gnome-initial-setup/cc-common-language.c
index 16dd28f..514a9b9 100644
--- a/gnome-initial-setup/cc-common-language.c
+++ b/gnome-initial-setup/cc-common-language.c
@@ -241,7 +241,7 @@ insert_language (GHashTable *ht,
char *label_untranslated;
char *key;
- locale = newlocale (LC_MESSAGES_MASK, lang, (locale_t) 0);
+ locale = newlocale (LC_ALL_MASK, lang, (locale_t) 0);
if (locale == (locale_t) 0) {
g_debug ("%s: Failed to create locale %s", G_STRFUNC, lang);
return;
diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c
index 3d48629..ffd1548 100644
--- a/gnome-initial-setup/gis-driver.c
+++ b/gnome-initial-setup/gis-driver.c
@@ -213,7 +213,7 @@ gis_driver_set_user_language (GisDriver *driver, const gchar *lang_id, gboolean
if (update_locale)
{
- locale_t locale = newlocale (LC_MESSAGES_MASK, lang_id, (locale_t) 0);
+ locale_t locale = newlocale (LC_ALL_MASK, lang_id, (locale_t) 0);
if (locale == (locale_t) 0)
{
g_warning ("Failed to create locale %s: %s", lang_id, g_strerror (errno));