Как изменить scancode-> keycodeсопоставление

Как изменить scancode-> keycodeсопоставление

Я переназначил клавишу Caps Lock на Backspace.

/etc/default/клавиатура

XKBLAYOUT="us"
XKBVARIANT="altgr-intl"
BACKSPACE="guess"
XKBOPTIONS="caps:backspace"

Это работает довольно хорошо, за исключением того, что это не работает для некоторых конкретных инструментов. Я использовал, xevчтобы выяснить, что происходит.

Нажата клавиша Backspace

KeyPress event, serial 38, synthetic NO, window 0x2400001,
    root 0x159, subw 0x0, time 1028211, (335,635), root:(452,749),
    state 0x10, keycode 22 (keysym 0xff08, BackSpace), same_screen YES,
    XLookupString gives 1 bytes: (08) "
    XmbLookupString gives 1 bytes: (08) "
    XFilterEvent returns: False

KeyRelease event, serial 38, synthetic NO, window 0x2400001,
    root 0x159, subw 0x0, time 1028272, (335,635), root:(452,749),
    state 0x10, keycode 22 (keysym 0xff08, BackSpace), same_screen YES,
    XLookupString gives 1 bytes: (08) "
    XFilterEvent returns: False

Нажата клавиша Caps Lock

KeyPress event, serial 38, synthetic NO, window 0x2400001,
    root 0x159, subw 0x0, time 859789, (391,558), root:(508,672),
    state 0x10, keycode 66 (keysym 0xff08, BackSpace), same_screen YES,
    XKeysymToKeycode returns keycode: 22
    XLookupString gives 1 bytes: (08) "
    XmbLookupString gives 1 bytes: (08) "
    XFilterEvent returns: False

KeyRelease event, serial 38, synthetic NO, window 0x2400001,
    root 0x159, subw 0x0, time 859875, (391,558), root:(508,672),
    state 0x10, keycode 66 (keysym 0xff08, BackSpace), same_screen YES,
    XKeysymToKeycode returns keycode: 22
    XLookupString gives 1 bytes: (08) "
    XFilterEvent returns: False

Я также попробовал это в браузере, используя

addEventListener('keyup', event => {
  console.log(event.keyCode, event.key, event.code)
})

Это регистрирует следующее, когда я нажимаю Backspace и Caps Lock

8 "Backspace" "Backspace"
8 "Backspace" "CapsLock"

Так что по сути мой caps lock переназначен на backspace, но это работает только если инструменты и веб-сайты используют надлежащие проверки. Я не хочу отправлять отчет об ошибке для каждого инструмента или веб-сайта, которые я когда-либо использовал, которые реализуют это неправильно.

Можно ли переназначить Caps Lock таким образом, чтобы он полностью эмулировал клавишу Backspace, а не действовал как переназначенный Caps Lock?

решение1

Сначала давайте посмотрим, как обрабатывается нажатие клавиши (взято изэтот ответ):

/клавиатура/ → scancode→ /драйвер ввода/ → keycode→ /X-сервер XKB/ →keysym

Это scancodeспецифичный для устройства код, который привязан к определенной клавише и может различаться у разных поставщиков/продуктов. keycodeи keysymраспространяются на приложения. keycodeСлужит в качестве уровня абстракции, поскольку он не зависит от устройства и локали. Он keycodeможет создавать разные keysyms в зависимости от локали и состояния клавиш-модификаторов. Вот почему некоторые приложения ищут только keycode, особенно при работе с сочетаниями клавиш.

Итак, наша цель — сопоставить scancodeклавишу CapsLock с keycodeклавишей BackSpace. Приложения будут видеть то же самое keycode, keysymнезависимо от того, нажимаете ли вы BackSpace или CapsLock.

Это отображение выполняетсяудевиспользуячасарджявляютсягатабase-файл (hwdb.bin), который скомпилирован из файлов .hwdb в форматах /lib/udev/hwdb.d/и /etc/udev/hwdb.d/​​.


Как изменить scancode-> keycodeсопоставление

Соберите необходимую информацию

Сначала вам нужно определить bustype, vendor, productи versionвашего устройства ввода (клавиатуры), а также scancodeклавишу, которую вы хотите переназначить, и , key code identifierна которую вы хотите ее сопоставить.

Запустите evtest(возможно, вам сначала придется установить его) и определите свою клавиатуру в списке устройств. На клавиатурах с дополнительными клавишами, такими как Play/Pause, WWW и т. д., эти клавиши часто отображаются как другое устройство ввода. Если при нажатии клавиши ничего не выводится, нажмите Control+ Cи попробуйте другое устройство. После того, как вы определите свою клавиатуру, запомните первый столбец ( /dev/input/eventX) и нажмите клавишу, которую вы хотите переназначить. Значение после (MSC_SCAN)scancode. На моей клавиатуре:

$ evtest
Available devices:
/dev/input/event0:  Power Button
/dev/input/event1:  Power Button
/dev/input/event2:  G19 Gaming Keyboard
/dev/input/event3:  G19 Gaming Keyboard
...
Select the device event number [0-18]:2
...
Event: time 1522111203.117945, -------------- SYN_REPORT ------------
Event: time 1522111220.778787, type 4 (EV_MSC), code 4 (MSC_SCAN),value 70039
Event: time 1522111220.778787, type 1 (EV_KEY), code 14 (KEY_BACKSPACE), value 1

... scancodeэто70039.

Теперь выполните следующую команду, где eventXнаходится та, которую вы выбрали ранее:

$ grep "" /sys/class/input/eventX/device/id/*

Вывод для моей клавиатуры:

/sys/class/input/event2/device/id/bustype:0003
/sys/class/input/event2/device/id/product:c228
/sys/class/input/event2/device/id/vendor:046d
/sys/class/input/event2/device/id/version:0110

Чтобы получить key code identifier, используйте вывод evtestили посмотрите наКлавиши и кнопкираздел /usr/include/linux/input-event-codes.hдля полного списка. Идентификатор — это часть после KEY_преобразования в нижний регистр, например, KEY_BACKSPACEстановитсявозврат на одну позицию.

Настроить udev

Взгляните на /lib/udev/hwdb.d/. Мы создадим текстовый файл в/etc/udev/hwdb.d/с именем файла, начинающимся с числа, большего, чем файл, соответствующий нашему типу устройства. Для клавиатуры это может быть любое число больше 60, а для указателя оно должно быть больше 70. Например 65-keyboard-custom.hwdb. Используйте ваш любимый текстовый редактор, но помните, что вы должны начать его как root, например

$ sudo gedit /etc/udev/hwdb.d/65-keyboard-custom.hwdb

Добавьте следующий контент

evdev:input:b[bustype]v[vendor]p[product]e[version]*
 KEYBOARD_KEY_[scancode]=[key code identifier]

...где

  • [bustype], [vendor], [product] и [version] имеют ровно 4 символа (при необходимости дополните нулями), а буквы должны бытьверхний регистр
  • [scancode] не нуждается в заполнении, но буквы должны бытьстрочные буквы
  • линия evdev:...имеетбез предшествующего пробела
  • линия KEYBOARD_KEY...имеетровно один предшествующий пробел

В моем примере файл выглядит так:

evdev:input:b0003v046DpC228e0110*
 KEYBOARD_KEY_70039=backspace   # map CapsLock to BackSpace

Первая строка будет сопоставлена ​​с вашим устройством. Вы можете указать дополнительные evdev:строки и использовать более одного подстановочного знака ( *) для сопоставления дополнительных устройств, но помните, что сканкоды специфичны для устройств. Вы также можете добавить более одного сопоставления сканкодов. Посмотрите /lib/udev/hwdb.d/60-keyboard.hwdbдля вдохновения. Более подробную и актуальную версию этого файла можно найти вонлайн-репозиторий.

Применить новую конфигурацию

Скомпилируйте новую конфигурацию в базу данных оборудования:

$ sudo systemd-hwdb update

Если вы хотите немедленно применить изменения, сообщите об этом udev:

$ sudo udevadm trigger

Обратите внимание, что значения конфигурации можно добавлять или изменять только во время работы системы. Если вы удалите конфигурацию (например, сопоставление сканкодов), вам придется перезагрузиться, чтобы изменения вступили в силу.

Не забудьте также отменить переназначение, которое вы сделали ранее (используя /etc/default/keyboard), поскольку оно все равно будет применено ко всем клавиатурам.

Связанный контент