Como mudar scancode-> keycodemapeamento

Como mudar scancode-> keycodemapeamento

Remapeei meu caps lock para backspace.

/etc/default/teclado

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

Isso funciona muito bem, exceto que não funciona para algumas ferramentas específicas. Eu costumava xevdescobrir o que estava acontecendo.

Backspace pressionado

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 pressionado

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

Eu também tentei no navegador usando

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

Isso registra o seguinte quando pressiono backspace e caps lock

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

Então, basicamente, meu caps lock é remapeado para backspace, mas só funciona se as ferramentas e sites usarem verificações adequadas. Não quero registrar um relatório de bug para cada ferramenta ou site que uso e que implemente isso incorretamente.

É possível mapear o caps lock de tal forma que ele emule totalmente um backspace em vez de agir como um caps lock remapeado?

Responder1

Primeiro, vamos ver como um pressionamento de tecla é processado (retirado deesta resposta):

/teclado/ → scancode→ /driver de entrada/ → keycode→ /servidor X XKB/ →keysym

É scancodeum código específico do dispositivo vinculado a uma chave específica e pode diferir entre diferentes fornecedores/produtos. keycodee keysymsão propagados para aplicativos. O keycodeserve como uma camada de abstração, pois é independente de dispositivo e de localidade. O mesmo keycodepode produzir keysyms diferentes, dependendo da localidade e do estado das teclas modificadoras. É por isso que alguns aplicativos procuram apenas o keycode, principalmente quando se trata de atalhos de teclado.

Portanto, nosso objetivo é mapear o valor scancodeda sua tecla CapsLock para o keycodevalor da tecla BackSpace. Os aplicativos verão o mesmo keycode, keysymindependentemente de você pressionar BackSpace ou CapsLock.

Esse mapeamento é feito porudevusando ohardocsãodatabase (hwdb.bin) que é compilado a partir de arquivos .hwdb em ambos /lib/udev/hwdb.d/e /etc/udev/hwdb.d/.


Como mudar scancode-> keycodemapeamento

Reúna as informações necessárias

Primeiro você deve determinar o bustype, vendore productdo versionseu dispositivo de entrada (teclado), bem como a scancodetecla que deseja remapear e para a qual key code identifierdeseja mapeá-la.

Execute evtest(talvez seja necessário instalá-lo primeiro) e identifique seu teclado na lista de dispositivos. Em teclados com teclas adicionais como Reproduzir/Pausar, WWW, etc., essas teclas são frequentemente expostas como um dispositivo de entrada diferente. Se você não obtiver nenhuma saída ao pressionar uma tecla, pressione Control+ Ce tente um dispositivo diferente. Depois de identificar seu teclado, lembre-se da primeira coluna ( /dev/input/eventX) e pressione a tecla que deseja remapear. O valor depois (MSC_SCAN)é o scancode. No meu teclado:

$ 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

... o scancodeé70039.

Agora execute o seguinte comando, onde eventXestá o que você escolheu antes:

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

A saída do meu teclado é

/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

Para obter o key code identifier, use a saída de evtestou observe oChaves e botõesseção /usr/include/linux/input-event-codes.hpara obter uma lista completa. O identificador é a parte depois de KEY_convertida para minúscula, por exemplo, KEY_BACKSPACEtorna-seretroceder.

Configurar o udev

Dê uma olhada /lib/udev/hwdb.d/. Criaremos um arquivo de texto em/etc/udev/hwdb.d/com um nome de arquivo começando com um número maior que o arquivo correspondente ao nosso tipo de dispositivo. Para um teclado, pode ser qualquer número maior que 60, enquanto para um ponteiro deve ser maior que 70. Por exemplo 65-keyboard-custom.hwdb. Use seu editor de texto favorito, mas lembre-se de que você deve iniciá-lo como root, por exemplo

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

Adicione o seguinte conteúdo

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

...onde

  • [bustype], [fornecedor], [produto] e [versão] possuem exatamente 4 caracteres (preenchido com zeros se necessário) e as letras precisam sermaiúsculas
  • [scancode] não precisa de preenchimento, mas as letras devem serminúscula
  • a evdev:...linha temsem espaço anterior
  • a KEYBOARD_KEY...linha temexatamente um espaço anterior

No meu exemplo, o arquivo fica assim:

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

A primeira linha corresponderá ao seu dispositivo. Você pode especificar evdev:linhas adicionais e usar mais de um curinga ( *) para corresponder a dispositivos adicionais, mas lembre-se de que os scancodes são específicos do dispositivo. Você também pode adicionar mais de um mapeamento de scancode. Dê uma olhada /lib/udev/hwdb.d/60-keyboard.hwdbpara se inspirar. Uma versão mais detalhada e atualizada desse arquivo pode ser encontrada norepositório on-line.

Aplicar nova configuração

Compile a nova configuração no banco de dados de hardware:

$ sudo systemd-hwdb update

Se você quiser aplicar as alterações imediatamente, informe ao udev:

$ sudo udevadm trigger

Observe que os valores de configuração só podem ser adicionados ou alterados enquanto o sistema está em execução. Se você remover uma configuração (por exemplo, mapeamento de scancode), será necessário reinicializar para que as alterações tenham efeito.

Lembre-se também de reverter o remapeamento feito antes (usando /etc/default/keyboard), pois isso ainda será aplicado a todos os teclados.

informação relacionada