Různá rozložení pro různé klávesnice

Aneb jak v Linuxu nastavit pro různé "klávesnice" různé rozložení a zajistit, aby to přežilo restart a přihlášení uživatele. Motivací bylo pořízení čtečky čárových kódů z aliexpressu. Na čtečce sice lze konfigurovat její rozložení, nicméně to české na ní zrovna nefungovalo. Reálně pokud je pak v systému nastavení česká klávesnice, tak čtečka místo čísel posílá diakritiku a tak podobně. Při nastavení US rozložení čtečka funguje normálně, ale zase na klávesnici tu diakritiku nenapíšem...

Krok 1: setxkbmap

setxkbmap je konzolový příkaz, který pod X11 změní rozložení klávesnice. setxkbmap us nastaví klávesnici na US rozložení, setxkbmap cz na českou. Zajímavá část nicméně je ta, že příkaz bere ještě parametr -device, kterým lze určit na kterém zařízení se mapa přepne. Výpis zařízení získáme příkazem xinput:
  1. ⎡ Virtual core pointer                        id=2    [master pointer  (3)]
  2. ⎜   ↳ Virtual core XTEST pointer                    id=4    [slave  pointer  (2)]
  3. ⎜   ↳ AcheronProject SharkPCB Mouse                 id=12   [slave  pointer  (2)]
  4. ⎜   ↳ AcheronProject SharkPCB Consumer Control      id=14   [slave  pointer  (2)]
  5. ⎜   ↳ Kensington ORBIT WIRELESS TB Mouse            id=15   [slave  pointer  (2)]
  6. ⎣ Virtual core keyboard                       id=3    [master keyboard (2)]
  7.     ↳ Virtual core XTEST keyboard                     id=5    [slave  keyboard (3)]
  8.     ↳ Power Button                                    id=6    [slave  keyboard (3)]
  9.     ↳ Video Bus                                       id=7    [slave  keyboard (3)]
  10.     ↳ Power Button                                    id=8    [slave  keyboard (3)]
  11.     ↳ HID 0581:0106 Keyboard                          id=9    [slave  keyboard (3)]
  12.     ↳ HID 0581:0106                                   id=10   [slave  keyboard (3)]
  13.     ↳ AcheronProject SharkPCB                         id=11   [slave  keyboard (3)]
  14.     ↳ AcheronProject SharkPCB System Control          id=13   [slave  keyboard (3)]
  15.     ↳ Kensington ORBIT WIRELESS TB Consumer Control   id=16   [slave  keyboard (3)]
To co je za id= je přesně ID, které se píše do parametru. V mém případě čtečka čárových kódů je zařízení s popisem "HID 0581:0106 Keyboard", takže setxkbmap -device 9 us přepne na čtečce rozložení na US a všechno ostatní zůstane funkční.

Krok 2: X11 server

Problém je, že tohle vydrží do prvního restartu X serveru (nebo počítače). A jsme zase tam, kde jsme byli. Takže nastavení se dá vynutit i přímo v konfiguraci X serveru. Takže do /etc/X11/xorg.conf.d/10-keyboard.conf jsem vecpal tento obsah:
  1. Section "InputClass"
  2.         Identifier "Shark"
  3.         MatchIsKeyboard "on"
  4.         MatchVendor "AcheronProject"
  5.  
  6.         Option "XkbLayout" "cz"
  7. EndSection
  8. Section "InputClass"
  9.         Identifier "barcode reader"
  10.         MatchVendor "0581"
  11.  
  12.         Option "XkbLayout" "us"
  13. EndSection
To nastavuje mé normální klávesnici (Acheron Shark) cz rozložení, čtečce us. Podle Vendor ID USB zařízení. To lze získat tak, že napřed zjistíme zařízení v systému (xinput list-props "HID 0581:0106 Keyboard" a koukáme na Device Node) a následně udevadm info --query=property --name=/dev/input/eventX (podle DeviceNode). Ve výpisu vezmeme ID_VENDOR a ten doplníme do konfiguračního souboru. Pokud systém nyní zrestartujeme, v login manageru by to nejspíše mělo fungovat. (A jak to udělat na waylandu nevím, ještě ho nikde nemám :-) )

Krok 3: desktop environment

Problém je, že pokud po přihlášení naběhne nějaké větší desktopové prostředí, u kterého je obvykle klikátko na nastavení klávesnice, nejspíše to zase zmrví. Na testovaném počítači jsem měl cinnamon a výsledkem bylo, že po naběhnutí stejně na všem nastavil rozložení, co měl v konfiguraci. No, spouštět vlastní příkazy po startu prostředí umíme, přes setxkbmap nastavit rozložení pro jedno zařízení umíme, takže co nám chybí? Jediný problém je to ID. Protože po nějakých upgradech, přeházení portů a podobně se může změnit. Tak si zbastlíme script:
  1. #!/bin/bash
  2.  
  3. BARCODE_ID=`xinput list --id-only "HID 0581:0106 Keyboard"`
  4. setxkbmap -device $BARCODE_ID us
Tradá, script si někam uložíme, v klikátku ho nastavíme jako aplikaci spouštěnou po startu a hotovo.