Meine Tastatur soll mit englischem Tastaturlayout laufen. Gleichzeitig muss das nervige CapsLock deaktiviert sein. Die Taste dient dann zusammen mit dem rechten Alt dem Setzen von Umlauten. CapsLock-q steht für ä, CapsLock-y für ü und CapsLock-p für ö. Um diese Belegung umzusetzen braucht es eine Mischung aus setxkbmap
und xmodmap
:
setxkbmap -variant altgr-intl -option -option compose:rctrl -option lv3:ralt_switch -option terminate:ctrl_alt_bkspc -option eurosign:e -option nbsp:level3n xmodmap /home/onli/.Xmodmap
Wobei in der .Xmodmap nur das hier steht:
clear lock keycode 66 = ISO_Level3_Shift NoSymbol ISO_Level3_Shift
Diese Befehle sendet meine ~/.icewm/startup bei jedem Login. Aber seit ich wegen der Heimarbeit regelmäßig die Tastatur zwischen Arbeitslaptop und eigenem PC wechselte, störte es mich langsam, dass ich nach jedem Wechsel bei angeschaltetem PC die Befehle neu ausführen musste. Das müsste man doch auch ohne Desktopumgebung automatisieren könnte. Desktopumgebungen wie KDE und Gnome könnten die Tastaturbelebung dauerhaft setzen, dafür ist dort meine Zielkonfiguration mit dem deaktivierten CapsLock und den erreichbaren Umlauten trotz US-Layout gar nicht so einfach umzusetzen.
Und tatsächlich gibt es für sowas udev. Damit können bei jedem Hardwarewechsel Berechtigungen gesetzt, Namen verteilt und eben auch beliebige Befehle ausgeführt werden. Doch leider ausgerechnet diese Tastaturumstellung nicht. Die Befehle werden einfach geschluckt, als ob nach udev nochmal der XServer auf den Hardwarewechsel reagiert und die Tastatur zurücksetzt. Zum Glück bin ich dann über diesen Artikel gestolpert, der zusammen mit einem Arch-Forenbeitrag beschreibt wie hier udev doch noch eingesetzt werden kann. Der Trick: Anstatt die Befehle direkt auszuführen schreibe in eine Datei, worauf ein inotify-Watcher reagiert daraufhin und im richtigen Kontext die Befehle ausführt.
Konfiguration udev
Wir starten mit udev. Zuerst gucken wir, wie die Tastatur identifiziert werden kann:
onli@fallout:~$ lsusb Bus 003 Device 002: ID 8087:8001 Intel Corp. … Bus 002 Device 007: ID 046a:a087 Cherry GmbH Wireless Mouse Bus 002 Device 009: ID 258a:1006 SINO WEALTH USB KEYBOARD
258a:1006
ist die gesuchte Kombination. Das packen wir nun in die udev-Regel unter /etc/udev/rules.d/80-ajazzmapping.rules (der Abschnitt vor .rules kann natürlich anders benannt werden):
ACTION!="add|change", GOTO="ajazz_rules_end" ATTRS{idVendor}=="258a", ATTRS{idProduct}=="1006", RUN+="/usr/local/bin/keyboard-udev.sh" LABEL="ajazz_rules_end"
Das Skript reagiert nur auf die Aktionen add oder change des Hardwaresystems, also wenn die Tastatur angesteckt wird. Per idVendor und idProduct schränken wir die Regel weiter ein auf genau die Hardwareidentifikatoren, die wir oben lsusb
entnomment haben. Und dann soll ein Skript ausgeführt werden.
Aktion: keyboard-udev.sh
Und zwar dieses, gespeichert als /usr/local/bin/keyboard-udev.sh:
#!/bin/bash # Path to lock file lock="/tmp/keyboard.lock" # Lock the file (other atomic alternatives would be "ln" or "mkdir") exec 9>"$lock" if ! flock -n 9; then notify-send -t 5000 "Keyboard script is already running." exit 1 fi echo '' > /tmp/keyboard.lock & # The lock file will be unlocked when the script ends
Das mit dem Lock ist gar nicht so ganz simpel, aber eigentlich müssen uns die Details hier nicht weiter interessieren. Wichtig ist: Nach /tmp/keyboard.lock wird geschrieben, und darauf können wir nun reagieren.
Die Reaktion
Dafür wird bei Start des Xservers der inotify-Watcher gestartet. Dafür kommt ein Aufruf zu file-inotify.sh
in die $HOME/.xinitrc, sodass sie bei mir nun so aussieht:
/usr/local/bin/keyboardMapping.sh file-inotify.sh /tmp/keyboard.lock /usr/local/bin/keyboardMapping.sh & # Triggered by udev rule xrdb -merge -I$HOME ~/.Xresources exec dbus-run-session /usr/bin/icewm-session --notray
file-inotify.sh müssen wir noch anlegen, ich erstellte es als /usr/local/bin/file-inotify.sh:
#!/bin/bash # Usage: file-inotify <file># Command is run when file is written. path=$(realpath "$1") job="$2" #basename=$(basename "$1") dirname=$(dirname "$1") inotifywait -m -e close_write --format '%w%f' "$dirname" \ | while read file do if [[ $(realpath "$file") == "$path" ]]; then sh -c "$job" fi done
Und die /usr/local/bin/keyboardMapping.sh? Das sind einfach die Tastatursetzbefehle von oben:
#!/bin/bash echo "remapping keyboard" setxkbmap -variant altgr-intl -option -option compose:rctrl -option lv3:ralt_switch -option terminate:ctrl_alt_bkspc -option eurosign:e -option nbsp:level3n xmodmap /home/onli/.Xmodmap
Die Tastatur sitzt
Jetzt steht das ganze System. Bei Systemstart wird per xinitrc der inotify-Watcher gestartet, der auf Dateisystemaktionen reagiert. Wenn udev das Einstöpseln der Tastatur mitbekommt schreibt es in die beobachtete Datei, woraufhin das Tastaturlayout gesetzt wird. Das funktioniert verlässlich und verursacht beim Warten keine Systemlast.
Die keyboardMapping.sh und damit die setxkbmap
- und xmodmap
-Befehle nicht manuell ausführen zu müssen ist an sich nur eine Kleinigkeit. Aber das automatisiert zu haben ist eine sehr angenehme Kleinigkeit. Ich vergaß es doch immer mal wieder, tippte daraufhin Unsinn zusammen und musste das Umschalten dann nachholen. So brauch ich nicht mehr dran zu denken.
onli blogging am : Der USB-Switch Aten US224, eine Heimarbeitserleichterung
Vorschau anzeigen