Оглавление

Тонкая настройка клавиатуры в Xorg

Я очень люблю горячие клавиши и использую их везде, где только можно. Иногда мне приходится подключаться к Xorg удалённо. По VNC или ещё как-нибудь. При этом, локальная система может использовать клавиши-модификаторы по-своему. Или она может вообще не обладать необходимыми клавишами.

Тогда бывает полезно создать эти клавиши самостоятельно.

Прежде всего, полезно посмотреть, как настроены модификаторы у вас сейчас. Речь, конечно, идёт об удалённой системе. На локальной мы ничего ломать не будем, а может даже и не можем, ведь локальной системой может быть, скажем, iPhone.

Посмотреть текущие настройки модификаторов можно командой xmodmap. Её вывод может выглядит примерно так:

xmodmap:  up to 2 keys per modifier, (keycodes in parentheses):

shift       Shift_L (0xa),  Shift_R (0xb)
lock
control     Control_L (0x8),  Control_R (0x9)
mod1        Alt_L (0xe),  Alt_R (0xf)
mod2
mod3
mod4        Meta_L (0xc),  Meta_R (0xd)
mod5

Допустим, вам нужен модификатор mod4.

Допустим, на вашей локальной системе, на которой вы запускаете клиента, нет клавиш Meta_L и Meta_R. Или эти клавиши присутствуют, но используются самой системой и не доходят до клиентского приложения.

Давайте сделаем клавишу-модификатор из какой-нибудь ненужной клавиши. Я, обычно, использую для этих целей F1 потому, как в реальной жизни она нужна меньше всего.

Сперва следует узнать код клавиши F1. На разных системах он может отличаться. Для этого запускаем xev, нажимаем клавишу F1 и изучаем вывод.

Среди прочего там будут строчки вида:

KeyPress event, serial 40, synthetic NO, window 0x1a00001,
    root 0x8b, subw 0x0, time 784155, (59,120), root:(895,143),
    state 0x0, keycode 67 (keysym 0xffbe, F1), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0x1a00001,
    root 0x8b, subw 0x0, time 784277, (59,120), root:(895,143),
    state 0x0, keycode 67 (keysym 0xffbe, F1), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

Здесь нам важно, что keycode 67. К этому цифровому коду нам надо привязать какой-нибудь модификатор. Пусть это будет Hyper_R. Выполняем команду

xmodmap -e 'keycode 67 = Hyper_R'

Убедиться, что всё получилось можно той же xev. Там вы увидите, что keysym стал не F1, а Hyper_R.

Теперь надо привязать синоним к модификатору. Внимание, даже если этот синоним уже привязан, его надо пере-привязать, так как разыменование синонима у кода клавиши происходит только в момент привязывания. То есть старый синоним был привязан ещё со старым кодом клавиши.

Поэтому, сперва числим наш модификатор.

xmodmap -e 'clear mod4'

а затем привязываем к нему наш синоним

xmodmap -e 'add mod4 = Hyper_R'

Всё. Теперь клавиша F1 будет работать как модификатор mod4. То есть, пока вы её держите, будут работать горячие клавиши, требующие модификатора mod4.

Следует заметить, что многие клавиатуры сконструированы так, что клавиши объединены в некоторые группы по несколько штук и одновременно могут быть нажаты только клавиши из разных групп.

То есть, возможно, на вашей клавиатуре вы не сможете нажать горячую клавишу <F1-F2>, где F1 — модификатор. Я встречался с такими казусами, но они ни разу не создали для меня заметных неудобств. Всегда можно перевесить модификатор куда-нибудь ещё.

Кстати,

Настроить переключение раскладки клавиатуры в Xorg

Можно тоже из командной строки. Примерно такой командой.

setxkbmap -layout us,ru -variant winkeys -option \
'grp:menu_toggle,grp_led:scroll,terminate:ctrl_alt_bksp,compose:ralt'

Здесь задано сразу множество опций (возможно вам они все не нужны):

Все эти же опции можно указать в /etc/X11/xorg.conf таким образом:

Section "InputClass"
  Identifier "system-keyboard"
  MatchIsKeyboard "on"
  Option "XkbLayout" "us,ru"
  Option "XkbVariant" "winkeys"
  Option "XkbOptions" "grp:menu_toggle,grp_led:scroll,terminate:ctrl_alt_bksp,compose:ralt"
  Option "XkbModel" "pc104"
EndSection

Такой подход имеет дополнительное полезное качество: если клавиатура была отключена/подключена, то настройки восстановятся. Если же вы настраивали клавиатуру из командной строки, то при «передёргивании» устройства, настройки свалятся на «умолчальные» настройки из конфига.

Если вы хотите сделать настройки модификаторов такими же перманентными, то вам надо посмотреть сюда /usr/share/X11/xkb/symbols и создать свой аналогичный XkbLayout-файл.

Небольшой практический этюд

Итак, я часто пользуюсь утилитой screen. Переключаться между окнами с помощью стандартных Ctrl-a-n, Ctrl-a-p довольно утомительно. Давайте приладим для этого дела стрелки.

Все модификаторы у меня для чего-нибудь заняты, но есть клавиша, которой я не пользуюсь. Это клавиша '/', расположенная в нижнем-левом углу клавиатуры.

Давайте сделаем из неё модификатор Mod3 (у меня он свободен), привязанный на Hyper_R. И заставить Mod3-[=>], Mod3-[<=] работать как Ctrl-a-n, Ctrl-a-p.

Настройка кнопки '/':

xmodmap -e 'keycode 94 = Hyper_R'
xmodmap -e 'clear mod3'
xmodmap -e 'add mod3 = Hyper_R'

Объясняем xterm наши намеренья:

xterm -xrm 'XTerm.VT100.translations: #override Mod3<Key>Left: string(0x1) string("p") \n Mod3<Key>Right: string(0x1) string("n")'

После тестирования, эту формулу можно перенести в .Xresources.