Por que eles não estão funcionando
De acordo com o artigo da ArchWiki que você mencionou:
-
O servidor X recebe códigos-chave do dispositivo de entrada e os converte para o estado e keysym .
-
estado é o bitmask dos modificadores X (Ctrl / Shift / etc).
-
keysym é (de acordo com
/usr/include/X11/keysymdef.h
) o inteiro queidentify characters or functions associated with each key (e.g., via the visible engraving) of a keyboard layout.
Cada caractere imprimível tem seu próprio keysym, como
plus
,a
,A
ouCyrillic_a
, mas outras chaves também geram seus keyyms, comoShift_L
,Left
ouF1
.
-
-
O aplicativo nos eventos de pressionamento / liberação de chave obtém todas essas informações.
Algumas aplicações controlam os keyyms como
Control_L
por si próprios, outros apenas procure pelos bits modificadores no estado .
Então o que acontece, quando você pressiona AltGr + j :
-
Você pressiona AltGr . Aplicativo recebe evento KeyPressed com keycode 108 (
<RALT>
) e keysym 0xfe03 (ISO_Level3_Shift
), o estado é 0. -
Você pressiona j (que mapeia para “h” no dvorak sem modificadores). Aplicativo recebe o evento KeyPressed com o código de acesso 44 (
<AC07>
), keysym 0xff51 (Left
) e estado 0x80 (o modificador Mod5 está ativado). -
Você libera j . O aplicativo recebe o evento KeyRelease para a chave
<AC07>
/Left
com os mesmos parâmetros. -
Em seguida, libere AltGr - evento KeyRelease para AltGr. (A propósito, o estado aqui ainda é 0x80, mas isso não importa.
Isso pode ser visto se você executar o utilitário xev
.
Então, isso tudo significa que, embora o aplicativo receba o mesmo código keysym
( Left
) a partir da chave normal <LEFT>
, também obtém o código keysym e
estado modificador do AltGr. Muito provavelmente, aqueles programas que não funcionam
observe os modificadores e não queira trabalhar quando alguns estiverem ativos.
Como fazê-los funcionar
Aparentemente, não podemos alterar todos os programas para não procurar modificadores. Então a única opção para escapar dessa situação é não gerar keyyms de modificadores e bits de estado.
1. Grupo separado
O único método que me vem à mente é: definir as teclas de movimento do cursor em um
grupo separado e alternar, com um pressionamento de tecla separado, para esse grupo antes de
pressionando as teclas j , k , l , i ( h
,
t
, n
, c
) (o agrupamento de grupos é o método preferido para um grupo de tempos
mudar, como eu entendo).
Por exemplo:
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)" };
};
Agora, se você pressionar AltGr pela primeira vez e, em seguida, (separadamente) um dos chaves de movimento, isso deve funcionar.
No entanto, isso não é muito útil, mais apropriado seria LockGroup
em vez de travar e pressione AltGr antes e depois da troca de grupo. Ainda melhor pode
seja para SetGroup
- então AltGr selecionaria esse grupo somente enquanto pressionado,
mas que divulga para as aplicações o keysym de AltGr
( ISO_Group_Shift
/ ISO_Group_Latch
/ whatever é definido) (mas estado modificador
fica limpo).
Mas ... também existe uma possibilidade de que o aplicativo também leia códigos de teclas (os códigos das chaves reais). Então, ele notará as teclas do cursor "falsas".
2. Sobreposição
A solução mais "de baixo nível" seria a sobreposição (como o mesmo artigo descreve).
Overlay significa simplesmente que alguma tecla (teclado real) retorna o código de tecla de outra chave. O servidor X altera o código de tecla de uma chave e calcula o modificador de estado e o keysym para esse novo código de acesso, então o aplicativo não deve notar a mudança.
Mas as sobreposições são muito limitadas:
- Existem apenas 2 bits de controle de sobreposição no servidor X (isto é, pode haver máximo de 2 sobreposições).
- Cada chave pode ter apenas 1 código de acesso alternativo.
Quanto ao resto, a implementação é bastante semelhante ao método com um grupo separado:
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
significa alterar o bit de controle enquanto a tecla é pressionada e restaurar
na liberação da chave. Deve haver uma função semelhante LatchControls
, mas
xkbcomp
me dá
Error: Unknown action LatchControls
na compilação de keymaps.
(A propósito, eu também uso dvorak e também remapeei alguns teclados de movimento para altos níveis de teclas alfabéticas. E também se deparou com algumas funcionalidades quebradas (seleção em notas Xfce e desktop switch por Ctrl-Alt-Esquerda / Direita). Graças a sua pergunta e esta resposta, agora eu sei o que é uma sobreposição:).