[gimp/wip/Jehan/fix-language-detect] app: detect system language with a more robust logic.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/Jehan/fix-language-detect] app: detect system language with a more robust logic.
- Date: Thu, 7 Jul 2022 17:02:05 +0000 (UTC)
commit 25e35e17fe57f9e4609152ea80eeb6b93bd60d7d
Author: Jehan <jehan girinstud io>
Date: Thu Jul 7 14:47:28 2022 +0200
app: detect system language with a more robust logic.
langinfo.h is not on all systems apparently and/or the locale item we
test for may not be available everywhere. Actually even on Linux, after
testing more deeply, I could create cases where nl_langinfo() would not
return a result (if the locale is broken through environment variable
for instance). setlocale() seems to always return usable value so far,
so I fallback on it. As a last resort, I look at environment variables
(even though these may contain invalid contents.
As for Windows and macOS, I try to use more platform-specific methods.
In macOS in particular, as I understood from reports, GIMP follows
correctly the language preference order, which means we should not look
at a single (top) lang, but at the whole list of prefered languages as a
single settings to determine whether the language was changed or not.
Should fix on Windows:
> fatal error: langinfo.h: No such file or directory
and on macOS:
> error: use of undeclared identifier '_NL_IDENTIFICATION_LANGUAGE'
app/language.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
configure.ac | 14 ++++++++++++
meson.build | 9 ++++++++
3 files changed, 87 insertions(+), 7 deletions(-)
---
diff --git a/app/language.c b/app/language.c
index f50bba737a..c1623f562d 100644
--- a/app/language.c
+++ b/app/language.c
@@ -21,7 +21,9 @@
#include "config.h"
+#ifdef HAVE__NL_IDENTIFICATION_LANGUAGE
#include <langinfo.h>
+#endif
#include <locale.h>
#include <glib.h>
@@ -30,10 +32,16 @@
#include <windows.h>
#include <winnls.h>
#endif
+#ifdef PLATFORM_OSX
+#include <Foundation/NSLocale.h>
+#endif
#include "language.h"
+static gchar * language_get_system_lang_id (void);
+
+
const gchar *
language_init (const gchar *language)
{
@@ -740,13 +748,7 @@ language_init (const gchar *language)
*/
if (! language || strlen (language) == 0)
{
- /* Using system language. It doesn't matter too much that the string
- * format is different when using system or preference-set language,
- * because this string is only used for comparison. As long as 2
- * similar run have the same settings, the strings will be
- * identical.
- */
- actual_language = g_strdup (nl_langinfo (_NL_IDENTIFICATION_LANGUAGE));
+ actual_language = language_get_system_lang_id ();
}
else
{
@@ -758,3 +760,58 @@ language_init (const gchar *language)
return actual_language;
}
+
+static gchar *
+language_get_system_lang_id (void)
+{
+ const gchar *syslang = NULL;
+
+ /* Using system language. It doesn't matter too much that the string
+ * format is different when using system or preference-set language,
+ * because this string is only used for comparison. As long as 2
+ * similar run have the same settings, the strings will be
+ * identical.
+ */
+#if defined G_OS_WIN32
+ return g_strdup_printf ("LANGID-%d", GetUserDefaultUILanguage());
+#elif defined PLATFORM_OSX
+ NSString *langs;
+
+ /* In macOS, the user sets a list of prefered languages and the
+ * software respects this preference order. I.e. that just storing the
+ * top-prefered lang would not be enough. What if GIMP didn't have
+ * translations for it, then it would fallback to the second lang. If
+ * this second lang changed, GIMP localization would change but we
+ * would not be aware of it. Instead, let's use the whole list as our
+ * language identifier. If this list changes in any way, we consider
+ * the lang may have potentially changed.
+ */
+ langs = [[NSLocale preferredLanguages] componentsJoinedByString:@","];
+
+ return g_strdup_printf ("%s", [langs UTF8String]);
+#elif defined HAVE__NL_IDENTIFICATION_LANGUAGE
+ syslang = nl_langinfo (_NL_IDENTIFICATION_LANGUAGE);
+#endif
+
+ if (syslang == NULL || strlen (syslang) == 0)
+ /* This should return an opaque string which represents the whole
+ * locale configuration on this system.
+ */
+ syslang = setlocale (LC_ALL, NULL);
+
+ /* I don't think we'd ever get here but just in case, as a last
+ * resort, if none of the previous methods returned a valid result,
+ * let's just check environment variables ourselves.
+ * This is the proper order of priority.
+ */
+ if (syslang == NULL || strlen (syslang) == 0)
+ syslang = g_getenv ("LANGUAGE");
+ if (syslang == NULL || strlen (syslang) == 0)
+ syslang = g_getenv ("LC_ALL");
+ if (syslang == NULL || strlen (syslang) == 0)
+ syslang = g_getenv ("LC_MESSAGES");
+ if (syslang == NULL || strlen (syslang) == 0)
+ syslang = g_getenv ("LANG");
+
+ return syslang && strlen (syslang) > 0 ? g_strdup (syslang) : NULL;
+}
diff --git a/configure.ac b/configure.ac
index ec85f0cdda..5ba0447c52 100644
--- a/configure.ac
+++ b/configure.ac
@@ -639,6 +639,20 @@ if test "$nl_ok" = "yes"; then
[Define to 1 if _NL_MEASUREMENT_MEASUREMENT is available])
fi
+# _NL_IDENTIFICATION_LANGUAGE is an enum and not a define
+AC_MSG_CHECKING([for _NL_IDENTIFICATION_LANGUAGE])
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <langinfo.h>]],
+ [[char c = *((unsigned char *) nl_langinfo(_NL_IDENTIFICATION_LANGUAGE));]])],
+ [nl_ok=yes],
+ [nl_ok=no])
+AC_MSG_RESULT($nl_ok)
+if test "$nl_ok" = "yes"; then
+ AC_DEFINE(HAVE__NL_IDENTIFICATION_LANGUAGE, 1,
+ [Define to 1 if _NL_IDENTIFICATION_LANGUAGE is available])
+fi
+
# Macro to keep track of failed dependencies.
required_deps=''
diff --git a/meson.build b/meson.build
index 19ff90c9d2..f29e9eacd8 100644
--- a/meson.build
+++ b/meson.build
@@ -286,6 +286,15 @@ conf.set('HAVE__NL_MEASUREMENT_MEASUREMENT',
''')
)
+conf.set('HAVE__NL_IDENTIFICATION_LANGUAGE',
+ cc.compiles('''
+ #include<langinfo.h>
+ int main() {
+ char c = *((unsigned char *) nl_langinfo(_NL_IDENTIFICATION_LANGUAGE));
+ }
+ ''')
+)
+
################################################################################
# Dependencies
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]