diff --git a/linux/keyman-config/keyman_config/downloadkeyboard.py b/linux/keyman-config/keyman_config/downloadkeyboard.py index 7eac44b5ecb..9d52506fc0a 100755 --- a/linux/keyman-config/keyman_config/downloadkeyboard.py +++ b/linux/keyman-config/keyman_config/downloadkeyboard.py @@ -3,6 +3,7 @@ import logging import os import urllib.parse +from keyman_config.keyman_locales import find_locales import gi @@ -30,7 +31,7 @@ def __init__(self, parent=None): self.webview = WebKit2.WebView() self.webview.connect("decide-policy", self._keyman_policy) self.webview.connect("load-changed", self._update_back_button) - url = KeymanComUrl + "/go/linux/" + __releaseversion__ + "/download-keyboards" + url = KeymanComUrl + "/go/linux/" + __releaseversion__ + "/download-keyboards" + "?lang=" + self._get_current_locale() self.webview.load_uri(url) s.add(self.webview) @@ -56,6 +57,12 @@ def __init__(self, parent=None): self.resize(800, 450) self.show_all() + def _get_current_locale(self): + loc = find_locales()[0] + if loc == "C": + loc = "en" + return loc.replace('_','-') + def _update_back_button(self, webview, load_event): self.back_button.set_sensitive(webview.can_go_back()) diff --git a/linux/keyman-config/keyman_config/keyman_locales.py b/linux/keyman-config/keyman_config/keyman_locales.py new file mode 100644 index 00000000000..b2480030aae --- /dev/null +++ b/linux/keyman-config/keyman_config/keyman_locales.py @@ -0,0 +1,41 @@ +#!/usr/bin/python3 +# +# Keyman is copyright (C) SIL Global. MIT License. +# +# Created by Marc Durdin on 2026-08-18 +# +# Find the current display locale ID, using the same method as +# gettext.find() +# + +import os +import re + +# +# @returns array of language identifiers in POSIX style, i.e. 'en_US', not 'en-US'. +# +# The returned array always includes the value 'C' for the default static locale, +# which should be replaced with 'en' when passed to other processes +# +def find_locales(): + # Approach comes from gettext.find() + languages = [] + for envvar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'): + val = os.environ.get(envvar) + if val: + # technically only LANGUAGE should have multiple entries, + # but we match gettext's implementation for consistency + languages = val.split(':') + break + if 'C' not in languages: + languages.append('C') + + # the env vars may also have .encoding or @modifier suffixes that we don't + # care about + # https://www.linux.com/news/controlling-your-locale-environment-variables/ + locale_ids = [] + for lang in languages: + locale_id = re.split(r"[.@]", lang) + locale_ids.append(locale_id[0]) + + return locale_ids diff --git a/linux/keyman-config/tests/keyman_locales_tests.py b/linux/keyman-config/tests/keyman_locales_tests.py new file mode 100644 index 00000000000..5e115d140f0 --- /dev/null +++ b/linux/keyman-config/tests/keyman_locales_tests.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# +# Keyman is copyright (C) SIL Global. MIT License. +# +# Created by Marc Durdin on 2026-08-19 +# +# Unit tests for find_locales +# +import os +from unittest import TestCase, mock +from keyman_config.keyman_locales import find_locales + +class FindLocalesTests(TestCase): + @mock.patch.dict(os.environ, {"LANGUAGE": "en_US.UTF-8:de_DE.UTF-8"}, True) + def test_find_locales_LANGUAGE(self): + loc = find_locales() + self.assertEqual(loc, ['en_US', 'de_DE', 'C']) + + @mock.patch.dict(os.environ, {"LANGUAGE": "en_US.UTF-8:de_DE.UTF-8", "LANG": "fr_FR"}, True) + def test_find_locales_LANGUAGE_and_LANG(self): + loc = find_locales() + self.assertEqual(loc, ['en_US', 'de_DE', 'C']) + + @mock.patch.dict(os.environ, {"LANG": "de_DE.UTF-8@euro"}, True) + def test_find_locales_LANG(self): + loc = find_locales() + self.assertEqual(loc, ['de_DE', 'C']) + + @mock.patch.dict(os.environ, {"LC_MESSAGES": "km_Khmr_KH.UTF-8"}, True) + def test_find_locales_LC_MESSAGES(self): + loc = find_locales() + self.assertEqual(loc, ['km_Khmr_KH', 'C']) + + @mock.patch.dict(os.environ, {"LC_ALL": "km_Khmr_KH.UTF-8"}, True) + def test_find_locales_LC_ALL(self): + loc = find_locales() + self.assertEqual(loc, ['km_Khmr_KH', 'C'])