From f6f6b4fbf1c9a0eb9ec66b0a94dfeabad4478b56 Mon Sep 17 00:00:00 2001 From: Softer Date: Thu, 2 Apr 2026 06:19:05 +0300 Subject: [PATCH 1/3] Set console font automatically when selecting language Add console_font field to languages.json and Language dataclass. When a language is activated, setfont is called automatically, falling back to default8x16 on error or for languages without a custom font. Also activate translation when loading language from config file. --- archinstall/lib/args.py | 1 + archinstall/lib/general/general_menu.py | 6 +++--- archinstall/lib/translationhandler.py | 28 ++++++++++++++++++++++++- archinstall/locales/languages.json | 2 +- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/archinstall/lib/args.py b/archinstall/lib/args.py index c61bc5a15f..8989edbd50 100644 --- a/archinstall/lib/args.py +++ b/archinstall/lib/args.py @@ -142,6 +142,7 @@ def from_config(cls, args_config: dict[str, Any], args: Arguments) -> Self: if archinstall_lang := args_config.get('archinstall-language', None): arch_config.archinstall_language = translation_handler.get_language_by_name(archinstall_lang) + translation_handler.activate(arch_config.archinstall_language) if disk_config := args_config.get('disk_config', {}): enc_password = args_config.get('encryption_password', '') diff --git a/archinstall/lib/general/general_menu.py b/archinstall/lib/general/general_menu.py index 5a95762ead..bd74378f01 100644 --- a/archinstall/lib/general/general_menu.py +++ b/archinstall/lib/general/general_menu.py @@ -106,9 +106,9 @@ async def select_archinstall_language(languages: list[Language], preset: Languag group = MenuItemGroup(items, sort_items=True) group.set_focus_by_value(preset) - title = 'NOTE: If a language can not displayed properly, a proper font must be set manually in the console.\n' - title += 'All available fonts can be found in "/usr/share/kbd/consolefonts"\n' - title += 'e.g. setfont LatGrkCyr-8x16 (to display latin/greek/cyrillic characters)\n' + title = 'NOTE: Console font will be set automatically for supported languages.\n' + title += 'For other languages, fonts can be found in "/usr/share/kbd/consolefonts"\n' + title += 'and set manually with: setfont \n' result = await Selection[Language]( header=title, diff --git a/archinstall/lib/translationhandler.py b/archinstall/lib/translationhandler.py index c7ce959bec..d897207706 100644 --- a/archinstall/lib/translationhandler.py +++ b/archinstall/lib/translationhandler.py @@ -2,6 +2,7 @@ import gettext import json import os +import subprocess from dataclasses import dataclass from pathlib import Path from typing import override @@ -14,6 +15,7 @@ class Language: translation: gettext.NullTranslations translation_percent: int translated_lang: str | None + console_font: str | None = None @property def display_name(self) -> str: @@ -31,6 +33,28 @@ def json(self) -> str: return self.name_en +_DEFAULT_FONT = 'default8x16' + + +def _set_console_font(font_name: str | None) -> None: + """ + Set the console font via setfont. + Falls back to default8x16 if font_name is None or setfont fails. + """ + target = font_name or _DEFAULT_FONT + + try: + result = subprocess.run(['setfont', target], capture_output=True, timeout=10) + if result.returncode != 0 and target != _DEFAULT_FONT: + subprocess.run(['setfont', _DEFAULT_FONT], capture_output=True, timeout=10) + except (FileNotFoundError, subprocess.TimeoutExpired, OSError): + if target != _DEFAULT_FONT: + try: + subprocess.run(['setfont', _DEFAULT_FONT], capture_output=True, timeout=10) + except (FileNotFoundError, subprocess.TimeoutExpired, OSError): + pass + + class TranslationHandler: def __init__(self) -> None: self._base_pot = 'base.pot' @@ -57,6 +81,7 @@ def _get_translations(self) -> list[Language]: abbr = mapping_entry['abbr'] lang = mapping_entry['lang'] translated_lang = mapping_entry.get('translated_lang', None) + console_font = mapping_entry.get('console_font', None) try: # get a translation for a specific language @@ -71,7 +96,7 @@ def _get_translations(self) -> list[Language]: # prevent cases where the .pot file is out of date and the percentage is above 100 percent = min(100, percent) - language = Language(abbr, lang, translation, percent, translated_lang) + language = Language(abbr, lang, translation, percent, translated_lang, console_font) languages.append(language) except FileNotFoundError as err: raise FileNotFoundError(f"Could not locate language file for '{lang}': {err}") @@ -133,6 +158,7 @@ def activate(self, language: Language) -> None: """ # The install() call has the side effect of assigning GNUTranslations.gettext to builtins._ language.translation.install() + _set_console_font(language.console_font) def _get_locales_dir(self) -> Path: """ diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index 1cc5cda434..2dbcf3b4d4 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -169,7 +169,7 @@ {"abbr": "tr", "lang": "Turkish", "translated_lang" : "Türkçe"}, {"abbr": "tw", "lang": "Twi"}, {"abbr": "ug", "lang": "Uighur"}, - {"abbr": "uk", "lang": "Ukrainian"}, + {"abbr": "uk", "lang": "Ukrainian", "console_font": "UniCyr_8x16"}, {"abbr": "ur", "lang": "Urdu", "translated_lang": "اردو"}, {"abbr": "uz", "lang": "Uzbek", "translated_lang": "O'zbek"}, {"abbr": "ve", "lang": "Venda"}, From e45995fa7103287dfe0a0b2841f9c887780f1ab3 Mon Sep 17 00:00:00 2001 From: Softer Date: Thu, 2 Apr 2026 21:47:15 +0300 Subject: [PATCH 2/3] Support FONT environment variable for console font override When FONT env var is set, use it as the console font instead of the language-specific font mapping from languages.json. The font is applied at startup and preserved across language switches. On exit (success or failure), restore the console font to default8x16. --- archinstall/lib/translationhandler.py | 4 +++- archinstall/main.py | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/archinstall/lib/translationhandler.py b/archinstall/lib/translationhandler.py index d897207706..903185d010 100644 --- a/archinstall/lib/translationhandler.py +++ b/archinstall/lib/translationhandler.py @@ -34,6 +34,7 @@ def json(self) -> str: _DEFAULT_FONT = 'default8x16' +_ENV_FONT = os.environ.get('FONT') def _set_console_font(font_name: str | None) -> None: @@ -158,7 +159,8 @@ def activate(self, language: Language) -> None: """ # The install() call has the side effect of assigning GNUTranslations.gettext to builtins._ language.translation.install() - _set_console_font(language.console_font) + + _set_console_font(_ENV_FONT if _ENV_FONT else language.console_font) def _get_locales_dir(self) -> Path: """ diff --git a/archinstall/main.py b/archinstall/main.py index ac072b0e84..5d46348895 100644 --- a/archinstall/main.py +++ b/archinstall/main.py @@ -16,7 +16,7 @@ from archinstall.lib.output import debug, error, info, warn from archinstall.lib.packages.util import check_version_upgrade from archinstall.lib.pacman.pacman import Pacman -from archinstall.lib.translationhandler import tr +from archinstall.lib.translationhandler import _ENV_FONT, _set_console_font, tr from archinstall.lib.utils.util import running_from_iso from archinstall.tui.ui.components import tui @@ -79,6 +79,9 @@ def run() -> int: OR straight as a module: python -m archinstall In any case we will be attempting to load the provided script to be run from the scripts/ folder """ + if _ENV_FONT: + _set_console_font(_ENV_FONT) + arch_config_handler = ArchConfigHandler() if '--help' in sys.argv or '-h' in sys.argv: @@ -159,6 +162,8 @@ def main() -> int: _error_message(exc) rc = 1 + _set_console_font(None) + return rc From 92c990d917b9f8a07bfdc9fee13411e173e46073 Mon Sep 17 00:00:00 2001 From: Softer Date: Thu, 2 Apr 2026 21:57:30 +0300 Subject: [PATCH 3/3] CI checks fix --- archinstall/lib/translationhandler.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/archinstall/lib/translationhandler.py b/archinstall/lib/translationhandler.py index 903185d010..53cd5f08be 100644 --- a/archinstall/lib/translationhandler.py +++ b/archinstall/lib/translationhandler.py @@ -45,13 +45,13 @@ def _set_console_font(font_name: str | None) -> None: target = font_name or _DEFAULT_FONT try: - result = subprocess.run(['setfont', target], capture_output=True, timeout=10) + result = subprocess.run(['setfont', target], capture_output=True, check=False, timeout=10) if result.returncode != 0 and target != _DEFAULT_FONT: - subprocess.run(['setfont', _DEFAULT_FONT], capture_output=True, timeout=10) + subprocess.run(['setfont', _DEFAULT_FONT], capture_output=True, check=False, timeout=10) except (FileNotFoundError, subprocess.TimeoutExpired, OSError): if target != _DEFAULT_FONT: try: - subprocess.run(['setfont', _DEFAULT_FONT], capture_output=True, timeout=10) + subprocess.run(['setfont', _DEFAULT_FONT], capture_output=True, check=False, timeout=10) except (FileNotFoundError, subprocess.TimeoutExpired, OSError): pass