Skip to content

Commit

Permalink
Adding dbus interface for loading locale keyboards
Browse files Browse the repository at this point in the history
  • Loading branch information
adamkankovsky committed Jan 14, 2025
1 parent a95908e commit 01ddb56
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
81 changes: 81 additions & 0 deletions pyanaconda/localization.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,87 @@ def get_territory_locales(territory):
return langtable.list_locales(territoryId=territory)


def normalize_language(lang):
"""Normalize the language string to extract the relevant part."""
parts = lang.split(".")[0].split("_")
return parts[1].lower() if len(parts) > 1 else parts[0]


def get_keyboard_layouts_for_language(lang):
"""Get keyboard layouts for the specified language.
:param lang: Language code string (e.g., "en_US.UTF-8")
:return: List of keyboard layout dictionaries
:raises: Exception if the file cannot be read or processed
"""
normalized_lang = normalize_language(lang)
file_path = "/usr/share/X11/xkb/rules/evdev.lst"

try:
with open(file_path, "r") as file:
content = file.read()
lines = content.strip().split("\n")

layouts = []
layout_map = {}
in_variant_section = False

# Parse the base layout IDs and store them in a map
for line in lines:
if line.startswith("! layout"):
in_variant_section = False
continue
elif line.startswith("! variant"):
in_variant_section = True
continue
elif line.startswith("! "):
in_variant_section = False

if not in_variant_section:
parts = re.split(r"\s+", line.strip())
if len(parts) >= 2:
layout_id = parts[0]
layout_name = " ".join(parts[1:]).strip()
layout_map[layout_id] = layout_name

# Parse the variant section and associate with layout IDs
in_variant_section = False
for line in lines:
if line.startswith("! variant"):
in_variant_section = True
continue
elif line.startswith("! "):
in_variant_section = False

if in_variant_section:
parts = re.split(r"\s+", line.strip())
if len(parts) > 1 and parts[1].startswith(f"{normalized_lang}:"):
variant_id = parts[0]
description = " ".join(parts[1:]).replace(f"{normalized_lang}:", "").strip()

# Find the base layout ID associated with this variant
base_layout_id = next(
(
layout_id for layout_id in layout_map
if parts[1].startswith(f"{normalized_lang}:") and layout_id in parts[1]
),
"unknown"
)

layouts.append({
"description": description,
"layoutId": base_layout_id,
"variantId": variant_id,
})

return layouts if layouts else [
{"description": "Default US layout", "layoutId": "us", "variantId": "us"}
]
except Exception as error:
log.error("Failed to process keyboard layouts for language %s: %s", lang, error)
raise


def get_locale_keyboards(locale):
"""Function returning preferred keyboard layouts for the given locale.
Expand Down
9 changes: 9 additions & 0 deletions pyanaconda/modules/localization/localization.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
get_available_translations,
get_common_languages,
get_english_name,
get_keyboard_layouts_for_language,
get_language_id,
get_language_locales,
get_native_name,
Expand Down Expand Up @@ -177,6 +178,14 @@ def get_locale_data(self, locale_id):

return tdata

def get_locale_keyboard_layouts(self, lang):
"""Get keyboard layouts for the specified language.
:param lang: Language code string (e.g., "en_US.UTF-8")
:return: List of keyboard layout dictionaries
"""
return get_keyboard_layouts_for_language(lang)

@property
def language(self):
"""Return the language."""
Expand Down
13 changes: 13 additions & 0 deletions pyanaconda/modules/localization/localization_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@ def GetLocaleData(self, locale_id: Str) -> Structure:
locale_data = self.implementation.get_locale_data(locale_id)
return LocaleData.to_structure(locale_data)

def GetLocaleKeyboardLayouts(self, lang: Str) -> List[Structure]:
"""Get keyboard layouts for the specified language.
For example: [
{"description": "US layout", "layoutId": "us", "variantId": ""},
{"description": "Czech QWERTY", "layoutId": "cz", "variantId": "qwerty"}
]
:param lang: Language code string (e.g., "en_US.UTF-8")
:return: List of keyboard layout dictionaries
"""
return self.implementation.get_locale_keyboard_layouts(lang)

@property
def Language(self) -> Str:
"""The language the system will use."""
Expand Down

0 comments on commit 01ddb56

Please sign in to comment.