Pourquoi ne travaillent-ils pas
Selon l' article d'ArchWiki que vous avez mentionné:
Serveur X reçoit les codes d' activation du dispositif d'entrée et les convertit à l'
état et keysym .
state est le masque binaire des modificateurs X (Ctrl / Shift / etc).
keysym est (selon /usr/include/X11/keysymdef.h
) l'entier qui
identifier les caractères ou fonctions associés à chaque touche (par exemple, via la gravure visible) d'une disposition de clavier.
Chaque personnage a son propre imprimable keysym, comme plus
, a
, A
ou
Cyrillic_a
, mais d' autres clés génèrent également leurs keysyms, comme
Shift_L
, Left
ou F1
.
L'application dans les événements clés de presse / libération obtient toutes ces informations.
Certaines applications suivent les keyymes comme Control_L
par elles-mêmes, d'autres recherchent simplement les bits de modification dans l' état .
Alors, que se passe-t-il lorsque vous appuyez sur AltGr+ j:
Vous appuyez AltGr. L'application obtient l'événement KeyPressed avec keycode 108 ( <RALT>
) et keysym 0xfe03 ( ISO_Level3_Shift
), l'état est 0.
Vous appuyez sur j(qui correspond à "h" dans dvorak sans modificateurs). L'application obtient l'événement KeyPressed avec keycode 44 ( <AC07>
), keysym 0xff51 ( Left
) et l'état 0x80 (le modificateur Mod5 est activé).
Vous relâchez j. L'application obtient l'événement KeyRelease pour la clé
<AC07>
/ Left
avec les mêmes paramètres.
Puis relâchez AltGr- événement KeyRelease pour AltGr. (Soit dit en passant, l'état ici est toujours 0x80, mais cela n'a pas d'importance.)
Cela peut être vu si vous exécutez l' xev
utilitaire.
Donc, cela signifie que, bien que l'application obtienne le même code keysym ( Left
) que la clé normale <LEFT>
, elle obtient également le code keysym et l'état du modificateur de l'AltGr. Très probablement, ces programmes qui ne fonctionnent pas, surveillent les modificateurs et ne veulent pas fonctionner lorsque certains sont actifs.
Comment les faire fonctionner
Apparemment, nous ne pouvons pas changer chaque programme pour ne pas chercher de modificateurs. Ensuite, la seule option pour échapper à cette situation est de ne pas générer les clés de clés et les bits d'état des modificateurs.
1. Groupe distinct
La seule méthode qui me vient à l' esprit est: définir les touches de déplacement du curseur dans un groupe séparé et commutateur, avec appui sur une touche séparée, à ce groupe avant d'appuyer sur les touches j, k, l, i( h
,
t
, n
, c
) (verrouillage groupe est la méthode préférée pour un changement de groupe de temps, si je comprends bien).
Par exemple:
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compatibility {
include "complete"
interpret ISO_Group_Latch { action = LatchGroup(group=2); };
};
xkb_symbols {
include "pc+us(dvorak)+inet(evdev)"
key <RALT> { [ ISO_Group_Latch ] };
key <AC07> {
type[Group2] = "ONE_LEVEL",
symbols[Group2] = [ Left ]
};
key <AC08> {
type[Group2] = "ONE_LEVEL",
symbols[Group2] = [ Down ]
};
key <AC09> {
type[Group2] = "ONE_LEVEL",
symbols[Group2] = [ Right ]
};
key <AD08> {
type[Group2] = "ONE_LEVEL",
symbols[Group2] = [ Up ]
};
};
xkb_geometry { include "pc(pc104)" };
};
Maintenant, si vous appuyez d'abord AltGret ensuite (séparément) sur l'une des touches de mouvement, cela devrait fonctionner.
Cependant, ce n'est pas très utile, il serait plus approprié de LockGroup
remplacer le verrouillage et d'appuyer sur AltGr avant et après le changement de groupe. Encore mieux peut-être SetGroup
- alors AltGr sélectionnerait ce groupe uniquement en appuyant dessus, mais cela révèle aux applications le clavier de AltGr ( ISO_Group_Shift
/ ISO_Group_Latch
/ quoi que ce soit défini) (mais l'état du modificateur reste propre).
Mais ... il est également possible que l'application lise également les codes clés (les codes des vraies clés). Ensuite, il remarquera les «fausses» touches de curseur.
2. Superposition
La solution la plus «bas niveau» serait la superposition (comme le même article le
décrit).
La superposition signifie simplement qu'une touche (clavier réel) renvoie le code de touche d'une autre touche. Le serveur X change le code clé d'une clé et calcule l'état du modificateur et le symbole de clé pour ce nouveau code clé, de sorte que l'application ne devrait pas remarquer le changement.
Mais les superpositions sont très limitées:
- Il n'y a que 2 bits de contrôle de superposition dans le serveur X (c'est-à-dire qu'il peut y avoir au maximum 2 superpositions).
- Chaque clé ne peut avoir qu'un seul code clé alternatif.
Pour le reste, l'implémentation est assez similaire à la méthode avec un groupe séparé:
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compatibility {
include "complete"
interpret Overlay1_Enable {
action = SetControls(controls=overlay1);
};
};
xkb_symbols {
include "pc+us(dvorak)+inet(evdev)"
key <RALT> {
type[Group1] = "ONE_LEVEL",
symbols[Group1] = [ Overlay1_Enable ]
};
key <AC07> { overlay1 = <LEFT> };
key <AC08> { overlay1 = <DOWN> };
key <AC09> { overlay1 = <RGHT> };
key <AD08> { overlay1 = <UP> };
};
xkb_geometry { include "pc(pc104)" };
};
SetControls
signifie changer le bit de contrôle pendant que la touche est enfoncée et le restaurer au relâchement de la touche. Il devrait y avoir une fonction similaire LatchControls
, mais
xkbcomp
me donne
Error: Unknown action LatchControls
sur la compilation de keymap.
(Soit dit en passant, j'utilise également dvorak et j'ai également remappé certaines touches de mouvement à des niveaux élevés de touches alphabétiques. votre question et cette réponse, maintenant je sais ce qu'est une superposition :).)