install.sh
Files / keyboard-layout / install.sh
Files in keyboard-layout/
Directorykeyboard-layout/
- custom-types 2.9 KB
- dvorak-qwerty 3.9 KB
- evdev.xml 661 bytes
- install.sh 4.8 KB
- LICENSE 1.0 KB
From Dvorak with QWERTY's brackets on KDE Plasma (Wayland). MIT licence: LICENSE.
#!/usr/bin/env bash# Installs the dvorak-qwerty keyboard layout (Dvorak, with QWERTY's [ ] { } - _ = + keys, and QWERTY# letters while Ctrl or Meta is held) into /etc/xkb and adds it after your current KDE layouts. Turns# on the XKB option custom:types for its key types, and sets Meta+Alt+K (Switch to Next Keyboard# Layout) when that shortcut is empty. KWin only searches /etc/xkb if it existed when KWin started,# so on the first install, log out and back in. Run as yourself, not with sudo: it asks for the# password once. Safe to run again. KDE Plasma 6 on Wayland.set -euo pipefail
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"name=dvorak-qwertyfail() { echo "๐ด $*"; echo "๐ด FAILED"; exit 1; }[[ $EUID -ne 0 ]] || fail "run it as yourself, not root: it changes your KDE settings"for f in "$name" custom-types evdev.xml; do [[ -f "$here/$f" ]] || fail "missing $here/$f (keep it next to this script)"; done
# 1. Compile checktmp="$(mktemp -d)"; trap 'rm -rf "$tmp"' EXITmkdir "$tmp/symbols" "$tmp/types" && cp "$here/$name" "$tmp/symbols/" && cp "$here/custom-types" "$tmp/types/custom"cat > "$tmp/km.xkb" <<EOFxkb_keymap { xkb_keycodes { include "evdev+aliases(qwerty)" }; xkb_types { include "complete+custom" }; xkb_compat { include "complete" }; xkb_symbols { include "pc+us+$name:2+inet(evdev)" };};EOFxkbcomp -w0 -I"$tmp" -xkb "$tmp/km.xkb" "$tmp/out.xkb" || fail "layout doesn't compile"echo "๐ข Layout compiles"
# 2. KWin reads /etc/xkb/symbols and /etc/xkb/types; System Settings lists layouts from# /etc/xkb/rules/evdev.xml. types/custom is a shared name: don't overwrite someone else's.if [[ -f /etc/xkb/types/custom ]] && ! grep -q DVQ_ALPHA /etc/xkb/types/custom; then fail "/etc/xkb/types/custom exists and isn't this layout's: merge custom-types into it by hand"fisudo install -Dm644 "$here/$name" "/etc/xkb/symbols/$name"sudo install -Dm644 "$here/custom-types" /etc/xkb/types/customsudo install -Dm644 "$here/evdev.xml" /etc/xkb/rules/evdev.xmlecho "๐ข Copied to /etc/xkb"
# 3. KDE settings in kxkbrc. --notify makes KWin reload, but only when a value changes.kr() { kreadconfig6 --file kxkbrc --group Layout --key "$1"; }kw() { kwriteconfig6 --notify --file kxkbrc --group Layout --key "$1" "$2"; }
# 3a. Option custom:types (loads types/custom). KWin only uses Options when ResetOldOptions is true;# otherwise it uses the system's (localectl), so start from those.options="$(kr Options)"[[ "$(kr ResetOldOptions)" == true ]] || options="$(localectl status | sed -n 's/^ *X11 Options: //p')"if [[ ",$options," == *",custom:types,"* ]]; then echo "๐ข Option custom:types already on"else options="${options:+$options,}custom:types" kw ResetOldOptions true kw Options "$options" echo "๐ข Options now: $options"fi
# 3b. Add the layout after the current ones. With no LayoutList yet, KWin uses the system layout.layouts="$(kr LayoutList)"; variants="$(kr VariantList)"if [[ -z "$layouts" ]]; then layouts="$(localectl status | sed -n 's/^ *X11 Layout: //p')" variants="$(localectl status | sed -n 's/^ *X11 Variant: //p')" layouts="${layouts:-us}"fiif [[ ",$layouts," == *",$name,"* ]]; then echo "๐ข Already in your layouts: $layouts"else IFS=, read -ra L <<< "$layouts"; IFS=, read -ra V <<< "$variants"; IFS=, read -ra N <<< "$(kr DisplayNames)" for i in "${!L[@]}"; do V[i]="${V[i]:-}"; N[i]="${N[i]:-}"; done L+=("$name"); V+=(""); N+=("dvq") kw Use true kw VariantList "$(IFS=,; echo "${V[*]}")" kw DisplayNames "$(IFS=,; echo "${N[*]}")" kw LayoutList "$(IFS=,; echo "${L[*]}")" echo "๐ข Layouts now: $(IFS=,; echo "${L[*]}")"fifor _ in 1 2 3 4 5; do sleep 1 loaded="$(qdbus6 --literal org.kde.keyboard /Layouts org.kde.KeyboardLayouts.getLayoutsList)" [[ "$loaded" == *"\"$name\""* ]] && breakdoneif [[ "$loaded" == *"\"$name\""* ]]; then echo "๐ข KWin has loaded it"else # The layout compiled in step 1, so it's KWin's search paths: journalctl -b _COMM=kwin_wayland | grep XKB-338 echo "๐ KWin hasn't loaded it yet: it only searches /etc/xkb if that existed when KWin started. Log out and back in"fi
# 4. Shortcut: kglobalaccel keys are a(ai), Meta+Alt+K = 0x10000000 + 0x08000000 + 0x4baction=("KDE Keyboard Layout Switcher" "Switch to Next Keyboard Layout" "Keyboard Layout Switcher" "Switch to Next Keyboard Layout")gacc=(busctl --user call org.kde.kglobalaccel /kglobalaccel org.kde.KGlobalAccel)case "$("${gacc[@]}" shortcutKeys as 4 "${action[@]}")" in "a(ai) 0" | "a(ai) 1 4 0 0 0 0") "${gacc[@]}" setForeignShortcutKeys 'asa(ai)' 4 "${action[@]}" 1 4 402653259 0 0 0 echo "๐ข Shortcut set: Meta+Alt+K" ;; *) echo "๐ข Layout shortcut already set, left as is" ;;esac
echo "๐ข SUCCESS: switch layouts with Meta+Alt+K or the tray icon (dvq), after a log-out if KWin hasn't loaded it"Text, photos and drawings: CC BY 4.0. Code: MIT. Share and adapt them, crediting HomeLab Guides (blog.jacq.cc). Licence and privacy