macOS: Set LANG to en_US if cocoa reports language as en_* that is not a valid locale

Fixes #3899
This commit is contained in:
Kovid Goyal 2021-08-05 06:29:21 +05:30
parent 276a82d1f7
commit 9e7253c179
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 32 additions and 6 deletions

View File

@ -22,6 +22,11 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
event which breaks some applications that grab the mouse but cant handle
mouse events (:iss:`3902`)
- macOS: When the language is set to English and the country to one for which
an English locale does not exist, set :envvar:`LANG` to ``en_US.UTF-8``
(:iss:`3899`)
0.22.2 [2021-08-02]
----------------------

View File

@ -66,6 +66,12 @@ Variables that influence kitty behavior
Variables that kitty sets when running child programs
.. envvar:: LANG
This is set only on macOS, and only if the country and language from the
macOS user settings form a valid locale.
.. envvar:: KITTY_WINDOW_ID
An integer that is the id for the kitty :term:`window` the program is running in.

View File

@ -574,12 +574,7 @@ cocoa_get_lang(PyObject UNUSED *self) {
locale = [[NSLocale currentLocale] localeIdentifier];
}
if (!locale) { Py_RETURN_NONE; }
// Make sure the locale value is valid, that is it can be used
// to construct an actual locale
const char* locale_utf8 = [locale UTF8String];
locale_t test_locale = newlocale(LC_ALL_MASK, locale_utf8, NULL);
if (!test_locale) { Py_RETURN_NONE; }
freelocale(test_locale);
return Py_BuildValue("s", locale_utf8);
} // autoreleasepool

View File

@ -23,6 +23,7 @@
#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <locale.h>
#ifdef WITH_PROFILER
#include <gperftools/profiler.h>
#endif
@ -156,6 +157,15 @@ wcwidth_wrap(PyObject UNUSED *self, PyObject *chr) {
return PyLong_FromLong(wcwidth_std(PyLong_AsLong(chr)));
}
static PyObject*
locale_is_valid(PyObject *self UNUSED, PyObject *args) {
char *name;
if (!PyArg_ParseTuple(args, "s", &name)) return NULL;
locale_t test_locale = newlocale(LC_ALL_MASK, name, NULL);
if (!test_locale) { Py_RETURN_FALSE; }
freelocale(test_locale);
Py_RETURN_TRUE;
}
static PyMethodDef module_methods[] = {
{"wcwidth", (PyCFunction)wcwidth_wrap, METH_O, ""},
@ -169,6 +179,7 @@ static PyMethodDef module_methods[] = {
{"parse_bytes", (PyCFunction)parse_bytes, METH_VARARGS, ""},
{"parse_bytes_dump", (PyCFunction)parse_bytes_dump, METH_VARARGS, ""},
{"redirect_std_streams", (PyCFunction)redirect_std_streams, METH_VARARGS, ""},
{"locale_is_valid", (PyCFunction)locale_is_valid, METH_VARARGS, ""},
#ifdef __APPLE__
METHODB(user_cache_dir, METH_NOARGS),
METHODB(process_group_map, METH_NOARGS),

View File

@ -672,6 +672,10 @@ def cocoa_get_lang() -> Optional[str]:
pass
def locale_is_valid(name: str) -> bool:
pass
def mark_os_window_for_close(os_window_id: int, cr_type: int = 2) -> bool:
pass

View File

@ -195,10 +195,15 @@ run_app = AppRunner()
def ensure_macos_locale() -> None:
# Ensure the LANG env var is set. See
# https://github.com/kovidgoyal/kitty/issues/90
from .fast_data_types import cocoa_get_lang
from .fast_data_types import cocoa_get_lang, locale_is_valid
if 'LANG' not in os.environ:
lang = cocoa_get_lang()
if lang is not None:
if not locale_is_valid(lang):
if lang.startswith('en_'):
lang = 'en_US'
else:
log_error(f'Could not set LANG Cocoa returns language as: {lang}')
os.environ['LANG'] = lang + '.UTF-8'