From 25a1b125b7d4be772b45949767a68bc8a9853fb0 Mon Sep 17 00:00:00 2001 From: bbedward Date: Sat, 4 Jul 2026 11:57:17 -0400 Subject: [PATCH] keyboard layout: add consistent helper to map layout codes to display fixes #1849 --- quickshell/Common/LayoutCodes.js | 107 ++++++++++++++++++ .../DankBar/Widgets/KeyboardLayoutName.qml | 107 +----------------- quickshell/Modules/Greetd/GreeterContent.qml | 13 +-- quickshell/Modules/Lock/LockScreenContent.qml | 13 +-- 4 files changed, 117 insertions(+), 123 deletions(-) create mode 100644 quickshell/Common/LayoutCodes.js diff --git a/quickshell/Common/LayoutCodes.js b/quickshell/Common/LayoutCodes.js new file mode 100644 index 000000000..9ab383129 --- /dev/null +++ b/quickshell/Common/LayoutCodes.js @@ -0,0 +1,107 @@ +.pragma library + +// English language name -> ISO 639-1 code, for abbreviating xkb layout names. +const LANG_CODES = { + "afrikaans": "af", + "albanian": "sq", + "amharic": "am", + "arabic": "ar", + "armenian": "hy", + "azerbaijani": "az", + "basque": "eu", + "belarusian": "be", + "bengali": "bn", + "bosnian": "bs", + "bulgarian": "bg", + "burmese": "my", + "catalan": "ca", + "chinese": "zh", + "croatian": "hr", + "czech": "cs", + "danish": "da", + "dutch": "nl", + "english": "en", + "esperanto": "eo", + "estonian": "et", + "filipino": "fil", + "finnish": "fi", + "french": "fr", + "galician": "gl", + "georgian": "ka", + "german": "de", + "greek": "el", + "gujarati": "gu", + "hausa": "ha", + "hebrew": "he", + "hindi": "hi", + "hungarian": "hu", + "icelandic": "is", + "igbo": "ig", + "indonesian": "id", + "irish": "ga", + "italian": "it", + "japanese": "ja", + "javanese": "jv", + "kannada": "kn", + "kazakh": "kk", + "khmer": "km", + "korean": "ko", + "kurdish": "ku", + "kyrgyz": "ky", + "lao": "lo", + "latvian": "lv", + "lithuanian": "lt", + "luxembourgish": "lb", + "macedonian": "mk", + "malay": "ms", + "malayalam": "ml", + "maltese": "mt", + "maori": "mi", + "marathi": "mr", + "mongolian": "mn", + "nepali": "ne", + "norwegian": "no", + "pashto": "ps", + "persian": "fa", + "iranian": "fa", + "farsi": "fa", + "polish": "pl", + "portuguese": "pt", + "punjabi": "pa", + "romanian": "ro", + "russian": "ru", + "serbian": "sr", + "sindhi": "sd", + "sinhala": "si", + "slovak": "sk", + "slovenian": "sl", + "somali": "so", + "spanish": "es", + "swahili": "sw", + "swedish": "sv", + "tajik": "tg", + "tamil": "ta", + "tatar": "tt", + "telugu": "te", + "thai": "th", + "tibetan": "bo", + "turkish": "tr", + "turkmen": "tk", + "ukrainian": "uk", + "urdu": "ur", + "uyghur": "ug", + "uzbek": "uz", + "vietnamese": "vi", + "welsh": "cy", + "yiddish": "yi", + "yoruba": "yo", + "zulu": "zu" +}; + +function layoutCode(layoutName) { + if (!layoutName) + return ""; + const lang = layoutName.split(" ")[0].toLowerCase(); + const code = LANG_CODES[lang] || lang.substring(0, 2); + return code.toUpperCase(); +} diff --git a/quickshell/Modules/DankBar/Widgets/KeyboardLayoutName.qml b/quickshell/Modules/DankBar/Widgets/KeyboardLayoutName.qml index 2fbcdf7d5..f7c0aa59a 100644 --- a/quickshell/Modules/DankBar/Widgets/KeyboardLayoutName.qml +++ b/quickshell/Modules/DankBar/Widgets/KeyboardLayoutName.qml @@ -5,6 +5,7 @@ import qs.Common import qs.Modules.Plugins import qs.Services import qs.Widgets +import "../../../Common/LayoutCodes.js" as LayoutCodes BasePill { id: root @@ -12,102 +13,6 @@ BasePill { property var widgetData: null property bool compactMode: widgetData?.keyboardLayoutNameCompactMode !== undefined ? widgetData.keyboardLayoutNameCompactMode : SettingsData.keyboardLayoutNameCompactMode property bool showIcon: widgetData?.keyboardLayoutNameShowIcon !== undefined ? widgetData.keyboardLayoutNameShowIcon : SettingsData.keyboardLayoutNameShowIcon - readonly property var langCodes: ({ - "afrikaans": "af", - "albanian": "sq", - "amharic": "am", - "arabic": "ar", - "armenian": "hy", - "azerbaijani": "az", - "basque": "eu", - "belarusian": "be", - "bengali": "bn", - "bosnian": "bs", - "bulgarian": "bg", - "burmese": "my", - "catalan": "ca", - "chinese": "zh", - "croatian": "hr", - "czech": "cs", - "danish": "da", - "dutch": "nl", - "english": "en", - "esperanto": "eo", - "estonian": "et", - "filipino": "fil", - "finnish": "fi", - "french": "fr", - "galician": "gl", - "georgian": "ka", - "german": "de", - "greek": "el", - "gujarati": "gu", - "hausa": "ha", - "hebrew": "he", - "hindi": "hi", - "hungarian": "hu", - "icelandic": "is", - "igbo": "ig", - "indonesian": "id", - "irish": "ga", - "italian": "it", - "japanese": "ja", - "javanese": "jv", - "kannada": "kn", - "kazakh": "kk", - "khmer": "km", - "korean": "ko", - "kurdish": "ku", - "kyrgyz": "ky", - "lao": "lo", - "latvian": "lv", - "lithuanian": "lt", - "luxembourgish": "lb", - "macedonian": "mk", - "malay": "ms", - "malayalam": "ml", - "maltese": "mt", - "maori": "mi", - "marathi": "mr", - "mongolian": "mn", - "nepali": "ne", - "norwegian": "no", - "pashto": "ps", - "persian": "fa", - "iranian": "fa", - "farsi": "fa", - "polish": "pl", - "portuguese": "pt", - "punjabi": "pa", - "romanian": "ro", - "russian": "ru", - "serbian": "sr", - "sindhi": "sd", - "sinhala": "si", - "slovak": "sk", - "slovenian": "sl", - "somali": "so", - "spanish": "es", - "swahili": "sw", - "swedish": "sv", - "tajik": "tg", - "tamil": "ta", - "tatar": "tt", - "telugu": "te", - "thai": "th", - "tibetan": "bo", - "turkish": "tr", - "turkmen": "tk", - "ukrainian": "uk", - "urdu": "ur", - "uyghur": "ug", - "uzbek": "uz", - "vietnamese": "vi", - "welsh": "cy", - "yiddish": "yi", - "yoruba": "yo", - "zulu": "zu" - }) readonly property var validVariants: ["US", "UK", "GB", "AZERTY", "QWERTY", "Dvorak", "Colemak", "Mac", "Intl", "International"] property string currentLayout: { if (CompositorService.isNiri) { @@ -140,11 +45,7 @@ BasePill { StyledText { text: { - if (!root.currentLayout) - return ""; - const lang = root.currentLayout.split(" ")[0].toLowerCase(); - const code = root.langCodes[lang] || lang.substring(0, 2); - return code.toUpperCase(); + return LayoutCodes.layoutCode(root.currentLayout); } font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText) color: Theme.widgetTextColor @@ -174,7 +75,7 @@ BasePill { const match = root.currentLayout.match(/^(\S+)(?:.*\(([^)]+)\))?/); if (match) { const lang = match[1].toLowerCase(); - const code = root.langCodes[lang] || lang.substring(0, 2); + const code = LayoutCodes.LANG_CODES[lang] || lang.substring(0, 2); if (match[2]) { const variant = match[2].trim(); const isValid = root.validVariants.some(v => variant.toUpperCase().includes(v.toUpperCase())) || variant.length <= 3; @@ -183,7 +84,7 @@ BasePill { } return code.toUpperCase(); } - return root.currentLayout.substring(0, 2).toUpperCase(); + return LayoutCodes.layoutCode(root.currentLayout); } return root.currentLayout; } diff --git a/quickshell/Modules/Greetd/GreeterContent.qml b/quickshell/Modules/Greetd/GreeterContent.qml index f992291f4..b5b583a87 100644 --- a/quickshell/Modules/Greetd/GreeterContent.qml +++ b/quickshell/Modules/Greetd/GreeterContent.qml @@ -10,6 +10,7 @@ import qs.Common import qs.Services import qs.Widgets import qs.Modules.Lock +import "../../Common/LayoutCodes.js" as LayoutCodes Item { id: root @@ -681,8 +682,7 @@ Item { } hyprlandKeyboard = mainKeyboard.name; if (mainKeyboard.active_keymap) { - const parts = mainKeyboard.active_keymap.split(" "); - hyprlandCurrentLayout = parts[0].substring(0, 2).toUpperCase(); + hyprlandCurrentLayout = LayoutCodes.layoutCode(mainKeyboard.active_keymap); } else { hyprlandCurrentLayout = ""; } @@ -1469,14 +1469,7 @@ Item { StyledText { text: { if (CompositorService.isNiri) { - const layout = NiriService.getCurrentKeyboardLayoutName(); - if (!layout) - return ""; - const parts = layout.split(" "); - if (parts.length > 0) { - return parts[0].substring(0, 2).toUpperCase(); - } - return layout.substring(0, 2).toUpperCase(); + return LayoutCodes.layoutCode(NiriService.getCurrentKeyboardLayoutName()); } else if (CompositorService.isHyprland) { return hyprlandCurrentLayout; } diff --git a/quickshell/Modules/Lock/LockScreenContent.qml b/quickshell/Modules/Lock/LockScreenContent.qml index 812f553e4..0cdd60969 100644 --- a/quickshell/Modules/Lock/LockScreenContent.qml +++ b/quickshell/Modules/Lock/LockScreenContent.qml @@ -12,6 +12,7 @@ import qs.Common import qs.Modals import qs.Services import qs.Widgets +import "../../Common/LayoutCodes.js" as LayoutCodes Item { id: root @@ -175,8 +176,7 @@ Item { } hyprlandKeyboard = mainKeyboard.name; if (mainKeyboard.active_keymap) { - const parts = mainKeyboard.active_keymap.split(" "); - hyprlandCurrentLayout = parts[0].substring(0, 2).toUpperCase(); + hyprlandCurrentLayout = LayoutCodes.layoutCode(mainKeyboard.active_keymap); } else { hyprlandCurrentLayout = ""; } @@ -1361,14 +1361,7 @@ Item { StyledText { text: { if (CompositorService.isNiri) { - const layout = NiriService.getCurrentKeyboardLayoutName(); - if (!layout) - return ""; - const parts = layout.split(" "); - if (parts.length > 0) { - return parts[0].substring(0, 2).toUpperCase(); - } - return layout.substring(0, 2).toUpperCase(); + return LayoutCodes.layoutCode(NiriService.getCurrentKeyboardLayoutName()); } else if (CompositorService.isHyprland) { return hyprlandCurrentLayout; }