Código-chave falso para as teclas do teclado remapeadas

1

Eu remapeei meu caps lock para backspace.

/ etc / default / keyboard

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

Isso funciona muito bem, exceto pelo fato de não funcionar para algumas ferramentas específicas. Eu usei xev para descobrir o que está 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 eu pressiono o retrocesso e o caps lock

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

Então, basicamente, meu caps lock é remapeado para backspace, mas só funciona se ferramentas e sites usarem verificações adequadas. Não quero enviar um relatório de erros para todas as ferramentas ou sites que eu uso que implementam isso incorretamente.

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

    
por Remco Haszing 26.03.2018 / 10:55

1 resposta

2

Primeiro, vamos ver como uma impressora de teclas é processada (tirada de esta resposta ):

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

O scancode é um código específico do dispositivo que é vinculado a uma chave específica e pode diferir entre diferentes fornecedores / produtos. keycode e keysym são propagados para aplicativos. O keycode serve como uma camada de abstração, pois é agnóstico de dispositivo e local independente. O mesmo keycode pode produzir diferentes keysym s, dependendo da localidade e do estado das teclas modificadoras. Essa é a razão pela qual alguns aplicativos procuram apenas o keycode , especialmente ao lidar com atalhos de teclado.

Portanto, nosso objetivo é mapear o scancode de sua chave CapsLock para o keycode da chave BackSpace. Os aplicativos verão, então, o mesmo keycode e keysym , independentemente de você pressionar BackSpace ou CapsLock.

Este mapeamento é feito por udev usando o h ard w são d ata b arquivo ase (hwdb.bin) que é compilado a partir de arquivos .hwdb em /lib/udev/hwdb.d/ e /etc/udev/hwdb.d/ .

Como alterar scancode - > keycode mapping

Reúna as informações necessárias

Primeiro, você precisa determinar o bustype , vendor , product e version do seu dispositivo de entrada (teclado), bem como o scancode da chave que você deseja remapear e o key code identifier você deseja mapeá-lo para.

Execute evtest (talvez você tenha que 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 + C e tente um dispositivo diferente. Depois de identificar o teclado, lembre-se da primeira coluna ( /dev/input/eventX ) e pressione a tecla que deseja remapear. O valor após (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, em que eventX é o que você escolheu antes:

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

A saída para o 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 evtest ou consulte a seção Chaves e botões em /usr/include/linux/input-event-codes.h para obter uma lista completa. O identificador é a parte depois de KEY_ convertido em minúsculas, por ex. KEY_BACKSPACE torna-se backspace .

Configurar o udev

Dê uma olhada em /lib/udev/hwdb.d/ . Vamos criar 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, esse pode ser qualquer número maior que 60, enquanto que para um bastão apontador deve ser maior que 70. Por exemplo, 65-keyboard-custom.hwdb . Use seu editor de texto favorito, mas lembre-se de que você precisa 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], [vendor], [product] e [version] têm exatamente quatro caracteres (preenchimento com zeros, se necessário) e as letras precisam ser maiúsculas
  • [scancode] não precisa de preenchimento, mas as letras precisam ser minúsculas
  • a linha evdev:... tem sem espaço anterior
  • a linha KEYBOARD_KEY... tem exatamente um espaço anterior

No meu exemplo, o arquivo é assim:

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

A primeira linha será correspondida ao seu dispositivo. Você pode especificar mais evdev: linhas e pode 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 em /lib/udev/hwdb.d/60-keyboard.hwdb para inspiração. Uma versão mais detalhada e atualizada desse arquivo pode ser encontrada no repositório on-line .

Aplicar nova configuração

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

$ sudo systemd-hwdb update

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

$ sudo udevadm trigger

Por favor, note 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 entrem em vigor.

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

    
por danzel 27.03.2018 / 15:04