web-dev-qa-db-fra.com

Faux code de clé pour les touches de clavier remappées

J'ai remappé mes majuscules sur backspace.

/ etc/default/keyboard

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

Cela fonctionne très bien, sauf que cela ne fonctionne pas pour certains outils spécifiques. J’ai utilisé xev pour savoir ce qui se passait.

Retour arrière enfoncé

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

Verrouillage des majuscules enfoncé

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

J'ai aussi essayé dans le navigateur en utilisant

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

Cela enregistre ce qui suit lorsque j'appuie sur la touche retour arrière et le verrouillage des majuscules

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

Donc, fondamentalement, mon verrouillage des majuscules est remappé en arrière-plan, mais cela ne fonctionne que si les outils et les sites Web utilisent les contrôles appropriés. Je ne veux pas déposer de rapport de bogue pour chaque outil ou site Web que j’utilise jamais et qui ne l’implémente pas correctement.

Est-il possible de mapper le verrouillage des majuscules de manière à émuler complètement un retour arrière au lieu d'agir comme un verrouillage des majuscules remappé?

1
Remco Haszing

Tout d’abord, voyons comment une touche est traitée (prise de cette réponse ):

/ clavier/→ scancode →/pilote d'entrée/→ keycode →/X serveur XKB/→ keysym

La scancode est un code spécifique à un périphérique, lié à une clé spécifique et pouvant différer entre différents fournisseurs/produits. keycode et keysym sont propagés aux applications. La variable keycode sert de couche d'abstraction, car elle est agnostique de périphérique et locale. Le même keycode peut produire différents keysyms, en fonction des paramètres régionaux et de l'état des touches de modification. C’est la raison pour laquelle certaines applications ne recherchent que le keycode, en particulier lorsqu’il s’agit de raccourcis clavier.

Notre objectif est donc de mapper la scancode de votre clé CapsLock sur la keycode de la clé BackSpace. Les applications verront alors les mêmes keycode et keysym, que vous appuyiez sur BackSpace ou sur CapsLock.

Ce mapping est fait par dev en utilisant le h ard w sont d ata b Fichier ase (hwdb.bin) compilé à partir des fichiers .hwdb à la fois dans /lib/udev/hwdb.d/ et /etc/udev/hwdb.d/.


Comment changer la correspondance scancode-> keycode

Recueillir les informations requises

Vous devez d’abord déterminer la bustype, vendor, product et version de votre périphérique d’entrée (clavier), ainsi que la scancode de la touche que vous avez sélectionnée. voulez remapper et le key code identifier auquel vous voulez le mapper.

Exécutez evtest (vous devrez peut-être d'abord l'installer) et identifiez votre clavier dans la liste des périphériques. Sur les claviers dotés de touches supplémentaires telles que Lecture/Pause, WWW, etc., ces touches sont souvent exposées en tant que périphérique d’entrée différent. Si vous n’obtenez aucune sortie lorsque vous appuyez sur une touche, appuyez sur Control+C et essayez un autre appareil. Une fois que vous avez identifié votre clavier, rappelez-vous la première colonne (/dev/input/eventX) et appuyez sur la touche que vous souhaitez remapper. La valeur après (MSC_SCAN) est la scancode. Sur mon clavier:

$ 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

... la scancode est 70039.

Maintenant, lancez la commande suivante, où eventX est celui que vous avez choisi auparavant:

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

La sortie pour mon clavier est

/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

Pour obtenir le key code identifier, utilisez le résultat de evtest ou consultez la section Touches et boutons de /usr/include/linux/input-event-codes.h pour obtenir une liste complète. L'identifiant est la partie après KEY_ convertie en minuscule, par exemple. KEY_BACKSPACE devient retour arrière.

Configurer udev

Jetez un coup d'œil à /lib/udev/hwdb.d/. Nous allons créer un fichier texte dans /etc/udev/hwdb.d/ avec un nom de fichier commençant par un nombre supérieur au fichier correspondant à notre type d'appareil. Pour un clavier, ce nombre peut être supérieur à 60, tandis que pour un stick pointeur, il doit être supérieur à 70. Par exemple, 65-keyboard-custom.hwdb. Utilisez votre éditeur de texte préféré, mais gardez à l’esprit que vous devez le démarrer en tant que root, par exemple.

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

Ajouter le contenu suivant

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

...où

  • [bustype], [vendor], [product] et [version] ont exactement 4 caractères (un pavé avec zéros si nécessaire) et les lettres doivent être majuscule
  • [scancode] n'a pas besoin de bourrage mais les lettres doivent être minuscule
  • la ligne evdev:... a aucun espace précédent
  • la ligne KEYBOARD_KEY... a exactement un espace précédent

Dans mon exemple, le fichier ressemble à ceci:

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

La première ligne sera adaptée à votre appareil. Vous pouvez spécifier d'autres lignes evdev: et utiliser plusieurs caractères génériques (*) pour faire correspondre des périphériques supplémentaires, mais gardez à l'esprit que les scancodes sont spécifiques à un périphérique. Vous pouvez également ajouter plusieurs mappages de scancode. Jetez un coup d'œil à /lib/udev/hwdb.d/60-keyboard.hwdb pour vous inspirer. Une version plus détaillée et à jour de ce fichier est disponible dans le référentiel en ligne .

Appliquer une nouvelle configuration

Compilez la nouvelle configuration dans la base de données matérielle:

$ Sudo systemd-hwdb update

Si vous souhaitez appliquer les modifications immédiatement, informez udev:

$ Sudo udevadm trigger

Veuillez noter que les valeurs de configuration ne peuvent être ajoutées ou modifiées que lorsque le système est en cours d'exécution. Si vous supprimez une configuration (par exemple, le mappage de scancode), vous devez redémarrer pour que les modifications prennent effet.

Pensez également à annuler le remappage que vous avez effectué précédemment (à l'aide de /etc/default/keyboard), car celui-ci sera toujours appliqué à tous les claviers.

2
danzel