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'
This commit is contained in:
parent
ccf6ecf43f
commit
25e35e17fe
3 changed files with 87 additions and 7 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
14
configure.ac
14
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=''
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue