From 98a9cd06880e10627868df5d11b97578ba18abca Mon Sep 17 00:00:00 2001 From: Ulrich Telle Date: Sun, 15 Jan 2023 15:17:44 +0100 Subject: [PATCH] Don't ignore LC_XXX in wxUILocaleImpl::GetPreferredUILanguages() Previously, if LANGUAGE was set, the other locale-related environment variables (LC_ALL, LC_MESSAGES, LANG) were simply ignored, which seems wrong as the user running the program after explicitly setting LC_ALL expects it to use this locale and not en_US from the default value of LANGUAGE on a typical Linux system using English. So handle LANGUAGE as a source of supplementary information, but still honour all the other environment variables. This goes against an explicit GNU gettext manual recommendation, but this recommendation seems to only make sense in the usual case, when the first element of LANGUAGE is the same as LC_ALL/LANG value, but not when they differ. See #23146. --- src/unix/uilocale.cpp | 45 ++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/unix/uilocale.cpp b/src/unix/uilocale.cpp index 11d084c474..c2a351c674 100644 --- a/src/unix/uilocale.cpp +++ b/src/unix/uilocale.cpp @@ -760,7 +760,29 @@ wxVector wxUILocaleImpl::GetPreferredUILanguages() // When the preferred UI language is determined, the LANGUAGE environment // variable is the primary source of preference. // http://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html - // + + // Since the first item in LANGUAGE is supposed to be equal to LANG resp LC_ALL, + // determine the default language based on the locale related environment variables + // as the first entry in the list of preferred languages. + wxString langFull; + wxString modifier; + if (GetLocaleFromEnvironment(langFull, modifier)) + { + if (!modifier.empty()) + { + // Locale name with modifier + if (const wxLanguageInfo* li = wxUILocale::FindLanguageInfo(langFull + modifier)) + { + preferred.push_back(li->CanonicalName); + } + } + // Locale name without modifier + if (const wxLanguageInfo* li = wxUILocale::FindLanguageInfo(langFull)) + { + preferred.push_back(li->CanonicalName); + } + } + // The LANGUAGE variable may contain a colon separated list of language // codes in the order of preference. // http://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html @@ -780,26 +802,19 @@ wxVector wxUILocaleImpl::GetPreferredUILanguages() return preferred; wxLogTrace(TRACE_I18N, " - LANGUAGE was set, but it didn't contain any languages recognized by the system"); } + else + { + wxLogTrace(TRACE_I18N, " - LANGUAGE was not set or empty, check LC_ALL, LC_MESSAGES, and LANG"); + } - wxLogTrace(TRACE_I18N, " - LANGUAGE was not set or empty, check LC_ALL, LC_MESSAGES, and LANG"); - - // first get the string identifying the language from the environment - wxString langFull, - modifier; - if (!GetLocaleFromEnvironment(langFull, modifier)) + if (preferred.empty()) { // no language specified, treat it as English langFull = "en_US"; + preferred.push_back(langFull); + wxLogTrace(TRACE_I18N, " - LC_ALL, LC_MESSAGES, and LANG were not set or empty, use English"); } - if (!modifier.empty()) - { - // Locale name with modifier - preferred.push_back(langFull + modifier); - } - // Locale name without modifier - preferred.push_back(langFull); - return preferred; }