Perché non funzionano?
Secondo l' articolo di ArchWiki che hai citato:
Il server X ottiene i codici chiave dal dispositivo di input e li converte nello
stato e nel keyym .
state è la maschera di bit dei modificatori X (Ctrl / Shift / etc).
keysym è (secondo /usr/include/X11/keysymdef.h
) il numero intero che
identificare i caratteri o le funzioni associate a ciascun tasto (ad es. tramite l'incisione visibile) di un layout di tastiera.
Ogni carattere stampabile ha un proprio keysym, come plus
, a
, A
, o
Cyrillic_a
, ma altri tasti generare anche i loro keysyms, come
Shift_L
, Left
o F1
.
L'applicazione nel tasto premi / rilascia eventi ottiene tutte queste informazioni.
Alcune applicazioni tengono traccia delle key palestra come Control_L
da sole, altre cercano semplicemente i bit modificatori nello stato .
Quindi cosa succede quando si preme AltGr+ j:
Tu premi AltGr. L'applicazione ottiene l'evento KeyPressed con keycode 108 ( <RALT>
) e keysym 0xfe03 ( ISO_Level3_Shift
), lo stato è 0.
Si preme j(che mappa su "h" in dvorak senza modificatori). L'applicazione ottiene l'evento KeyPressed con keycode 44 ( <AC07>
), keysym 0xff51 ( Left
) e stato 0x80 (il modificatore Mod5 è attivo).
Rilasci j. L'applicazione ottiene l'evento KeyRelease per la chiave
<AC07>
/ Left
con gli stessi parametri.
Quindi rilasciare AltGr- Evento KeyRelease per AltGr. (A proposito, lo stato qui è ancora 0x80, ma non importa.)
Questo può essere visto se si esegue l' xev
utilità.
Quindi, tutto ciò significa che, sebbene l'applicazione ottenga lo stesso codice keysym ( Left
) della chiave normale <LEFT>
, ottiene anche il codice keysym e lo stato modificatore da AltGr. Molto probabilmente, quei programmi che non funzionano, guardano i modificatori e non vogliono lavorare quando alcuni sono attivi.
Come farli funzionare
Apparentemente, non possiamo cambiare ogni programma per non cercare modificatori. Quindi l'unica opzione per sfuggire a questa situazione è quella di non generare i keymont dei modificatori e i bit di stato.
1. Gruppo separato
L'unico metodo che viene in mente è: definire tasti di movimento del cursore in un gruppo e interruttore separato, premendo un tasto separato, a quel gruppo prima premendo i tasti j, k, l, i( h
,
t
, n
, c
) (gruppo di bloccaggio è il metodo preferito per una volta il cambio di gruppo, come ho capito).
Per esempio:
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)" };
};
Ora, se prima premi AltGre poi (separatamente) uno dei tasti di movimento, questo dovrebbe funzionare.
Tuttavia, questo non è molto utile, sarebbe più appropriato LockGroup
invece di agganciare e premere AltGr prima e dopo il cambio di gruppo. Ancora meglio potrebbe essere SetGroup
- allora AltGr selezionerebbe quel gruppo solo mentre viene premuto, ma questo rivela alle applicazioni il keyym di AltGr ( ISO_Group_Shift
/ ISO_Group_Latch
/ qualunque cosa sia definito) (ma lo stato del modificatore rimane pulito).
Ma ... c'è anche la possibilità che l'applicazione legga anche i codici chiave (i codici delle chiavi reali). Quindi noterà i tasti cursore "falso".
2. Sovrapposizione
La soluzione più "di basso livello" sarebbe la sovrapposizione (come
descritto nello stesso articolo ).
Overlay significa semplicemente che un tasto (tastiera reale) restituisce il codice tasto di un altro tasto. Il server X cambia il codice chiave di una chiave e calcola lo stato del modificatore e il keyym per quel nuovo codice chiave, quindi l'applicazione non dovrebbe notare la modifica.
Ma le sovrapposizioni sono molto limitate:
- Esistono solo 2 bit di controllo overlay nel server X (ovvero possono esserci al massimo 2 overlay).
- Ogni chiave può avere solo 1 codice chiave alternativo.
Per il resto, l'implementazione è abbastanza simile al metodo con un gruppo separato:
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 cambiare il bit di controllo mentre il tasto è premuto e ripristinarlo al rilascio del tasto. Dovrebbe esserci una funzione simile LatchControls
, ma
xkbcomp
mi dà
Error: Unknown action LatchControls
sulla compilazione di keymap.
(A proposito, uso anche dvorak e ho anche rimappato alcune tastiere di movimento ad alti livelli di chiavi alfabetiche. E ho anche riscontrato alcune funzionalità rotte (selezione nelle note di Xfce e cambio desktop da Ctrl-Alt-Sinistra / Destra). Grazie a la tua domanda e questa risposta, ora so cos'è un overlay :).)