Por que eles não estão trabalhando?
De acordo com o artigo do ArchWiki que você mencionou:
O servidor X obtém códigos de chave do dispositivo de entrada e os converte em
estado e código de chave .
state é a máscara de bit dos modificadores X (Ctrl / Shift / etc).
keysym é (de acordo com /usr/include/X11/keysymdef.h
) o número inteiro que
identifique caracteres ou funções associadas a cada tecla (por exemplo, através da gravação visível) de um layout de teclado.
Cada personagem de impressão tem a sua própria keysym, como plus
, a
, A
, ou
Cyrillic_a
, mas outras teclas também gerar os seus keysyms, como
Shift_L
, Left
ou F1
.
O aplicativo nos principais eventos de imprensa / liberação obtém todas essas informações.
Alguns aplicativos rastreiam academias de teclas como Control_L
eles mesmos, outros apenas procuram os bits modificadores no estado .
Então, o que acontece, quando você pressiona AltGr+ j:
Você pressiona AltGr. O aplicativo obtém o evento KeyPressed com o código de chave 108 ( <RALT>
) e o código de chave 0xfe03 ( ISO_Level3_Shift
), o estado é 0.
Você pressiona j(que mapeia para "h" no dvorak sem modificadores). O aplicativo obtém o evento KeyPressed com o código de chave 44 ( <AC07>
), keysym 0xff51 ( Left
) e o estado 0x80 (o modificador Mod5 está ativado).
Você solta j. O aplicativo obtém o evento KeyRelease da 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 xev
utilitário.
Portanto, isso significa que, embora o aplicativo obtenha o mesmo código Left
de chave de chave ( ) da chave normal <LEFT>
, ele também obtém o código de chave de chave e o estado modificador do AltGr. Provavelmente, aqueles programas que não funcionam, assistem aos modificadores e não querem trabalhar quando alguns estão ativos.
Como fazê-los funcionar
Aparentemente, não podemos mudar todos os programas para não procurar modificadores. Então, a única opção para escapar dessa situação é não gerar as classes de teclas e os bits de estado dos modificadores.
1. Grupo separado
O único método que vem à cabeça é: definir teclas de movimento do cursor num grupo e comutador separado, com uma prensa de chave separada, para que o grupo antes de pressionar as teclas j, k, l, i( h
,
t
, n
, c
) (grupo de bloqueio é o método preferido por uma mudança de grupo de tempo, 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 primeiro AltGre depois (separadamente) uma das teclas de movimento, isso funcionará.
No entanto, isso não é muito útil, seria mais apropriado, em LockGroup
vez de travar, e pressionar AltGr antes e depois da troca de grupo. Ainda melhor SetGroup
: AltGr selecionaria esse grupo apenas enquanto pressionado, mas isso revela aos aplicativos o keyym do AltGr ( ISO_Group_Shift
/ ISO_Group_Latch
/ o que for definido) (mas o estado do modificador permanece limpo).
Mas ... existe também a possibilidade de o aplicativo também ler códigos de chave (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 outra tecla. O servidor X altera o código de chave de uma chave e calcula o estado do modificador e o código de chave desse novo código de chave, para que o aplicativo não note a alteração.
Mas as sobreposições são muito limitadas:
- Existem apenas 2 bits de controle de sobreposição no servidor X (ou seja, pode haver no máximo 2 sobreposições).
- Cada chave pode ter apenas 1 código de chave 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 mudar o bit de controle enquanto a tecla é pressionada e restaurá-lo na liberação da tecla. Deve haver função semelhante LatchControls
, mas
xkbcomp
me dá
Error: Unknown action LatchControls
na compilação de mapas de teclado.
(A propósito, eu também uso o dvorak e também remapeei algumas academias de teclas de movimento para altos níveis de teclas alfabéticas. E também deparei com algumas funcionalidades quebradas (seleção nas notas do Xfce e alternância na área de trabalho por Ctrl-Alt-Esquerda / Direita). sua pergunta e esta resposta, agora eu sei o que é uma sobreposição :).)