Add curated XKB option presets
This commit is contained in:
@@ -10,9 +10,9 @@ local prefs = require("prefs")
|
||||
hl.config({
|
||||
input = {
|
||||
kb_layout = prefs.get("keyboardLayout", "us"),
|
||||
kb_variant = "",
|
||||
kb_variant = prefs.get("keyboardVariant", ""),
|
||||
kb_model = "",
|
||||
kb_options = "",
|
||||
kb_options = prefs.get("keyboardOptions", ""),
|
||||
kb_rules = "",
|
||||
|
||||
numlock_by_default = prefs.get("numlockByDefault", true),
|
||||
|
||||
@@ -21,6 +21,25 @@ SettingsPage {
|
||||
// when nothing is being captured. Held here rather than per row so that
|
||||
// starting a new capture cancels any other.
|
||||
property string capturingChord: ""
|
||||
readonly property string storedXkbOptions: String(DesktopPreferences.get("keyboardOptions") ?? "")
|
||||
|
||||
function xkbOptions(): var {
|
||||
return root.storedXkbOptions
|
||||
.split(",")
|
||||
.map(option => option.trim())
|
||||
.filter(option => option !== "");
|
||||
}
|
||||
|
||||
function currentXkbOption(prefix: string): string {
|
||||
return root.xkbOptions().find(option => option.indexOf(prefix) === 0) ?? "";
|
||||
}
|
||||
|
||||
function setXkbOption(prefix: string, option: string): void {
|
||||
const options = root.xkbOptions().filter(option => option.indexOf(prefix) !== 0);
|
||||
if (option !== "")
|
||||
options.push(option);
|
||||
SystemSettings.commitPreference("keyboardOptions", options.join(","));
|
||||
}
|
||||
|
||||
title: "Input & Shortcuts"
|
||||
lede: "The Forge mental model, carried forward into native tiling."
|
||||
@@ -35,6 +54,52 @@ SettingsPage {
|
||||
// they are real controls.
|
||||
TextEntryRow { setting: "keyboardLayout"; placeholder: "us" }
|
||||
TextEntryRow { setting: "keyboardVariant"; placeholder: "none" }
|
||||
|
||||
ChoiceGrid {
|
||||
width: parent.width
|
||||
label: "Caps Lock"
|
||||
detail: "Keep it conventional, or turn a prime keyboard position into Escape or Control"
|
||||
current: root.currentXkbOption("caps:")
|
||||
options: [
|
||||
{ value: "", label: "Standard" },
|
||||
{ value: "caps:escape_shifted_capslock", label: "Esc · Shift for Caps" },
|
||||
{ value: "caps:escape", label: "Escape" },
|
||||
{ value: "caps:ctrl_modifier", label: "Control" }
|
||||
]
|
||||
onPicked: value => root.setXkbOption("caps:", value)
|
||||
}
|
||||
|
||||
ChoiceGrid {
|
||||
width: parent.width
|
||||
label: "Compose key"
|
||||
detail: "Type accented characters and symbols with memorable key sequences"
|
||||
current: root.currentXkbOption("compose:")
|
||||
options: [
|
||||
{ value: "", label: "Off" },
|
||||
{ value: "compose:ralt", label: "Right Alt" },
|
||||
{ value: "compose:rwin", label: "Right Super" },
|
||||
{ value: "compose:menu", label: "Menu" }
|
||||
]
|
||||
onPicked: value => root.setXkbOption("compose:", value)
|
||||
}
|
||||
|
||||
ChoiceGrid {
|
||||
width: parent.width
|
||||
label: "Layout switching"
|
||||
detail: "Used when Keyboard layout contains more than one comma-separated layout"
|
||||
current: root.currentXkbOption("grp:")
|
||||
options: [
|
||||
{ value: "", label: "Off" },
|
||||
{ value: "grp:win_space_toggle", label: "Super + Space" },
|
||||
{ value: "grp:alt_shift_toggle", label: "Alt + Shift" },
|
||||
{ value: "grp:ctrl_shift_toggle", label: "Ctrl + Shift" },
|
||||
{ value: "grp:caps_toggle", label: "Caps Lock" }
|
||||
]
|
||||
onPicked: value => root.setXkbOption("grp:", value)
|
||||
}
|
||||
|
||||
// Presets preserve every option outside their own category. The raw
|
||||
// value remains visible for less common xkeyboard-config features.
|
||||
TextEntryRow { setting: "keyboardOptions"; placeholder: "compose:ralt" }
|
||||
SliderRow { setting: "keyRepeatDelay" }
|
||||
SliderRow { setting: "keyRepeatRate" }
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Common XKB behavior should be discoverable without hiding the raw option
|
||||
# string from advanced users. This is source-only so it never remaps the live
|
||||
# keyboard while the desktop is in use.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
page="$repo_dir/config/dot/quickshell/modules/settings/ShortcutsPage.qml"
|
||||
input="$repo_dir/config/dot/hypr/input.lua"
|
||||
|
||||
fail() {
|
||||
printf 'xkb presets contract: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
for needle in \
|
||||
'function currentXkbOption(prefix: string): string' \
|
||||
'function setXkbOption(prefix: string, option: string): void' \
|
||||
'label: "Caps Lock"' \
|
||||
'value: "caps:escape_shifted_capslock"' \
|
||||
'value: "caps:ctrl_modifier"' \
|
||||
'label: "Compose key"' \
|
||||
'value: "compose:ralt"' \
|
||||
'label: "Layout switching"' \
|
||||
'value: "grp:win_space_toggle"' \
|
||||
'SystemSettings.commitPreference("keyboardOptions"' \
|
||||
'TextEntryRow { setting: "keyboardOptions"'; do
|
||||
rg -Fq "$needle" "$page" || fail "Shortcuts is missing $needle"
|
||||
done
|
||||
|
||||
# Picking one category must replace only that category, preserving advanced
|
||||
# options from every other group.
|
||||
rg -Fq 'option.indexOf(prefix) !== 0' "$page" \
|
||||
|| fail 'preset updates do not preserve unrelated XKB options'
|
||||
|
||||
rg -Fq 'kb_variant = prefs.get("keyboardVariant", "")' "$input" \
|
||||
|| fail 'Hyprland does not replay the stored keyboard variant'
|
||||
rg -Fq 'kb_options = prefs.get("keyboardOptions", "")' "$input" \
|
||||
|| fail 'Hyprland does not replay the stored keyboard options'
|
||||
|
||||
printf 'xkb presets contract: PASS\n'
|
||||
Reference in New Issue
Block a user