¿Por qué no están trabajando?
Según el artículo de ArchWiki que mencionaste:
El servidor X obtiene códigos de clave del dispositivo de entrada y los convierte al
estado y keyym .
El estado es la máscara de bits de los modificadores X (Ctrl / Shift / etc).
keyym es (según /usr/include/X11/keysymdef.h
) el entero que
identificar caracteres o funciones asociadas con cada tecla (por ejemplo, a través del grabado visible) de una distribución de teclado.
Cada personaje tiene su propia imprimible keysym, como plus
, a
, A
, o
Cyrillic_a
, pero otras teclas también generan sus teclas keysyms, como
Shift_L
, Left
o F1
.
La aplicación en los eventos de pulsación / liberación de teclas obtiene toda esta información.
Algunas aplicaciones rastrean los símbolos de teclas como Control_L
si fueran ellos mismos, otras solo buscan los bits modificadores en el estado .
Entonces, ¿qué sucede cuando presionas AltGr+ j:
Se presiona AltGr. La aplicación obtiene el evento KeyPressed con el código de tecla 108 ( <RALT>
) y keyym 0xfe03 ( ISO_Level3_Shift
), el estado es 0.
Presiona j(que se asigna a "h" en dvorak sin modificadores). La aplicación obtiene el evento KeyPressed con el código <AC07>
clave 44 ( ), keyym 0xff51 ( Left
) y el estado 0x80 (el modificador Mod5 está activado).
Tu liberas j. La aplicación obtiene el evento KeyRelease para la clave
<AC07>
/ Left
con los mismos parámetros.
Luego AltGr, suelte el evento KeyRelease para AltGr. (Por cierto, el estado aquí sigue siendo 0x80, pero eso no importa).
Esto se puede ver si ejecuta la xev
utilidad.
Entonces, todo eso significa que, aunque la aplicación obtiene el mismo código keyym ( Left
) que la clave normal <LEFT>
, también obtiene el código keyym y el estado modificador del AltGr. Lo más probable es que los programas que no funcionan, miren los modificadores y no quieran funcionar cuando algunos están activos.
Cómo hacer que funcionen
Aparentemente, no podemos cambiar todos los programas para no buscar modificadores. Entonces, la única opción para escapar de esta situación es no generar los keyyms de los modificadores y los bits de estado.
1. grupo separado
El único método que viene a la mente es: definir teclas de movimiento del cursor en un grupo y un interruptor separado, con una pulsación de tecla por separado, a ese grupo antes de pulsar las teclas j, k, l, i( h
,
t
, n
, c
) (grupo de bloqueo es el método preferido por un cambio de grupo de tiempo, según tengo entendido).
Por ejemplo:
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)" };
};
Ahora, si primero presiona AltGry luego (por separado) una de las teclas de movimiento, esto debería funcionar.
Sin embargo, esto no es muy útil, sería más apropiado en LockGroup
lugar de enganchar y presionar AltGr antes y después del cambio de grupo. Incluso puede ser mejor SetGroup
, entonces AltGr seleccionaría ese grupo solo mientras se presiona, pero eso revela a las aplicaciones el teclado de AltGr ( ISO_Group_Shift
/ ISO_Group_Latch
/ lo que sea que esté definido) (pero el estado del modificador se mantiene limpio).
Pero ... también queda la posibilidad de que la aplicación también lea códigos clave (los códigos de las claves reales). Entonces notará las teclas de cursor "falsas".
2. Superposición
La solución más "de bajo nivel" sería la superposición (como se
describe en el mismo artículo ).
Superponer simplemente significa que alguna tecla (teclado real) devuelve el código de otra tecla. El servidor X cambia el código clave de una clave y calcula el estado del modificador y el keyym para ese nuevo código clave, por lo que la aplicación no debería notar el cambio.
Pero las superposiciones son muy limitadas:
- Solo hay 2 bits de control de superposición en el servidor X (es decir, puede haber un máximo de 2 superposiciones).
- Cada clave puede tener solo 1 código clave alternativo.
En cuanto al resto, la implementación es bastante similar al método con un 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 cambiar el bit de control mientras se presiona la tecla y restaurarlo al soltar la tecla. Debería haber una función similar LatchControls
, pero
xkbcomp
me da
Error: Unknown action LatchControls
en la compilación de mapas de teclas.
(Por cierto, también uso dvorak y también he reasignado algunos keyyms de movimiento a altos niveles de teclas alfabéticas. Y también encontré algunas funciones rotas (selección en notas Xfce y cambio de escritorio con Ctrl-Alt-Izquierda / Derecha). Gracias a su pregunta y esta respuesta, ahora sé lo que es una superposición :).)