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 879695c
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
72 changes: 72 additions & 0 deletions pyanaconda/localization.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,78 @@ 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_locale_keyboard_layouts(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.keys() 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(f"Failed to process keyboard layouts for language {lang}: {error}")
raise


def get_locale_keyboards(locale):
"""Function returning preferred keyboard layouts for the given locale.
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 879695c

Please sign in to comment.