minigalaxy icon indicating copy to clipboard operation
minigalaxy copied to clipboard

using wrong default locale

Open TayouVR opened this issue 7 months ago • 4 comments

in the background are plasma locale settings, showing american english as language. minigalaxy is using german for some reason.

Image I assume it picked up my locale from one of the other values here, not from LANG?
$> locale
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=en_US.UTF-8
LC_CTYPE=de_DE.UTF-8
LC_NUMERIC=de_DE.UTF-8
LC_TIME=en_DE.UTF-8
LC_COLLATE=de_DE.UTF-8
LC_MONETARY=de_DE.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_PAPER=de_DE.UTF-8
LC_NAME=de_DE.UTF-8
LC_ADDRESS=en_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MEASUREMENT=de_DE.UTF-8
LC_IDENTIFICATION=de_DE.UTF-8
LC_ALL=

TayouVR avatar Aug 03 '25 07:08 TayouVR

Minigalaxy has a configuration option that takes priority. If that is not set, the fallback looks up the default locale with python locale.getdefaultlocale. According to the docs, python has a certain algorithm to look up the language based on some env vars. But i dont know the full order and priority.

It'd be interesting to see how exactly plasma controls languages of applications it starts. Which variables does it set and how? And whats your locale setting when you start a non-graphical terminal for your user from outside plasma (e.g. by ssh-ing).

GB609 avatar Aug 03 '25 08:08 GB609

If this is a Flatpak installation, it could be this bug: https://github.com/flathub/io.github.sharkwouter.Minigalaxy/issues/11

sharkwouter avatar Aug 03 '25 15:08 sharkwouter

I am using the nixpkgs package. Here is how that is built: https://github.com/NixOS/nixpkgs/blob/0d00f23f023b7215b3f1035adb5247c8ec180dbc/pkgs/by-name/mi/minigalaxy/package.nix

but going by that comment I assume this may be a python issue? I talked to some other people, who do more with python and heard something about python using the keyboard layout as locale, which would match this behaviour, since I do use a german layout keyboard.

TayouVR avatar Aug 03 '25 17:08 TayouVR

It is a bit of both. Python has a very peculiar mechanism and look up priority for locale settings. But the code in minigalaxy dealing with localization has room for improvement as well.

TL;DR: By default, python checks LC_ALL, LC_CTYPE, LANG and LANGUAGE in that order for a valid locale. But we should be able to control that by manually passing another order of variables to check.

Python about locale.getdefaultlocale:

locale.getdefaultlocale([envvars])

Tries to determine the default locale settings and returns them as a tuple of the form (language code, encoding).

According to POSIX, a program which has not called setlocale(LC_ALL, '') runs using the portable 'C' locale. Calling setlocale(LC_ALL, '') lets it use the default locale as defined by the LANG variable. Since we do not want to interfere with the current locale setting we thus emulate the behavior in the way described above.

To maintain compatibility with other platforms, not only the LANG variable is tested, but a list of variables given as envvars parameter. The first found to be defined will be used. envvars defaults to the search path used in GNU gettext; it must always contain the variable name 'LANG'. The GNU gettext search path contains 'LC_ALL', 'LC_CTYPE', 'LANG' and 'LANGUAGE', in that order.

Additionally, i've had a look into the code. I think we're doing something inconsistent with setting and reading env vars and locale, in addition to the behavior of python. Locale handling is done in 2 files:

  • translation.py
  • ui/window.py

From what i can see, translation.py starts out correctly by setting LC_ALL='' which should force python to use LANG (or rather, the lookup path). But then, a few lines down, LANGUAGEand LANG are unset and locale.getdefaultlocale() is used afterwards. But LANG is not set there anymore. Which is why it will fall back to getting the keyboard layout for language in the later call. Settings or unsetting LANG like this here is a problem of in itself as well, because it propagates to games being launched from minigalaxy. Some old games (or wine games) don't have language settings on their own and depend on the locale setting.

The second location is in window.init() which gets called a bit later. This one again fetches the current locale based on locale.getdefaultlocate(), if the config in minigalaxy wasn't used and then sets it using locale.setlocale(). If i understand the python docs correctly, we - in theory - wouldn't need to call locale.setlocale() if minigalaxy has no own config to override it, because setlocale(LC_ALL, '') should configure python to use what is in LANG. I guess it's been placed there because of ui tests which had localization issues because the initialization from translation.py was not correct (or not loaded).

I think we should re-organize this and move part of the code in window.init() to translation.py. If a call to locale.setlocale() is required, it should happen once and at a central place. Littering this across several files is just confusing and hard to follow. Ideally, tests should be written in a way that they are neutral in regards to localization, or set up their environment (which does lead to issues with building on machines where the target locale is not installed).

GB609 avatar Aug 04 '25 09:08 GB609