GNU/Linux >> Linux Esercitazione >  >> Linux

Come fare in modo che tutte le applicazioni rispettino il mio layout xkb modificato?

Perché non funzionano

Secondo l'articolo di ArchWiki che hai citato:

  • Il server X riceve i codici chiave dal dispositivo di input e li converte nellostato e keysym .

    • stato è la maschera di bit dei modificatori X (Ctrl/Shift/etc).

    • keysym è (secondo /usr/include/X11/keysymdef.h ) il numero interothat

      identificare i caratteri o le funzioni associate a ciascun tasto (ad esempio, tramite l'incisione visibile) di un layout di tastiera.

      Ogni carattere stampabile ha il proprio keysym, come plus , a , A , oCyrillic_a , ma anche altre chiavi generano i propri keysym, comeShift_L , Left o F1 .

  • L'applicazione negli eventi di stampa/rilascio chiave ottiene tutte queste informazioni.

    Alcune applicazioni tengono traccia dei keysym come Control_L da soli, altri semplicemente cercano i bit modificatori nello stato .

Quindi cosa succede quando premi AltGr +j :

  • Premi AltGr . L'applicazione ottiene l'evento KeyPressed con keycode108 (<RALT> ) e keysym 0xfe03 (ISO_Level3_Shift ), lo stato è 0.

  • Premi j (che esegue il mapping a "h" in dvorak senza modificatori). L'applicazione riceve l'evento KeyPressed con codice tasto 44 (<AC07> ), keysym 0xff51(Left ) e stato 0x80 (il modificatore Mod5 è attivo).

  • Rilasci j . L'applicazione riceve l'evento KeyRelease per la chiave<AC07> /Left con gli stessi parametri.

  • Poi rilascia AltGr — Evento KeyRelease per AltGr. (A proposito, lo stato qui è ancora 0x80, ma non importa.)

Questo può essere visto se esegui xev utilità.

Quindi, tutto ciò significa che, sebbene l'applicazione ottenga lo stesso codice keysym(Left ) come dalla normale chiave <LEFT> , ottiene anche il codice keysym e lo stato del modificatore da AltGr. Molto probabilmente, quei programmi che non funzionano, guardano i modificatori e non vogliono funzionare quando alcuni sono attivi.

Come farli funzionare

Apparentemente, non possiamo cambiare ogni programma per non cercare i modificatori. Quindi l'unica opzione per sfuggire a questa situazione è non generare keysyms e bit di stato dei modificatori.

1. Gruppo separato

L'unico metodo che mi viene in mente è:definire i tasti di movimento del cursore in un gruppo separato e passare, con una pressione di tasto separata, a quel gruppo prima di premere i tasti j , k , l , io (h ,t , n , c ) (la chiusura del gruppo è il metodo preferito per un cambio di gruppo una tantum, a quanto ho capito).

Ad 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 AltGr e poi (separatamente) uno dei tasti di movimento, questo dovrebbe funzionare.

Tuttavia, questo non è molto utile, sarebbe più appropriato LockGroup invece di bloccare e premere AltGr prima e dopo il cambio di gruppo. Ancora meglio forse a SetGroup — quindi AltGr selezionerebbe quel gruppo solo mentre viene premuto, ma questo rivela alle applicazioni il keysym(ISO_Group_Shift di AltGr /ISO_Group_Latch /qualunque cosa sia definita) (ma il modificatore state rimane pulito).

Ma... c'è anche la possibilità che l'applicazione legga anche i keycode (i codici delle chiavi reali). Quindi noterà i tasti cursore "falsi".

2. Sovrapposizione

La soluzione più "di basso livello" sarebbe l'sovrapposizione (come descrive lo stesso articolo).

Sovrapponi significa semplicemente che un tasto (della 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 keysym per quel nuovo codice chiave, quindi l'applicazione non dovrebbe notare il cambiamento.

Ma le sovrapposizioni sono molto limitate:

  • Ci sono solo 2 bit di controllo dell'overlay nel server X (ovvero possono esserci al massimo 2 overlay).
  • Ogni chiave può avere solo 1 codice chiave alternativo.

Per quanto riguarda 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 modificare il bit di controllo mentre il tasto è premuto e ripristinarlo al rilascio del tasto. Dovrebbe esserci una funzione simile LatchControls , maxkbcomp mi dà

Error:            Unknown action LatchControls

sulla compilazione della mappa dei tasti.

(A proposito, uso anche dvorak e ho anche rimappato alcuni simboli di tasti di movimento ad alti livelli di tasti alfabetici. E ho anche riscontrato alcune funzionalità interrotte (selezione nelle note di Xfce e cambio desktop con Ctrl-Alt-Sinistra/Destra). Grazie alla tua domanda e questa risposta, ora so cos'è un overlay :).)


Come farli funzionare - Soluzione 3

Utilizzo di livelli aggiuntivi e Action RedirectKey

La seguente soluzione utilizza il tasto Alt sinistro per fornire i tasti cursore su jkli, Home/Fine/PaginaSu/PaginaGiù su uopö e Canc su Backspace.

Il tasto Alt sinistro rimane utilizzabile per altri scopi per tutti gli altri tasti (come per il menu dell'applicazione). L'Alt sinistro (Mod1) viene rimosso dallo stato del modificatore quando viene utilizzato il blocco del cursore in modo che le applicazioni non possano vederlo.

xkb_keymap {
    xkb_keycodes { 
        include "evdev+aliases(qwertz)" 
    };
    xkb_types { 
        include "complete"  
    };
    xkb_compat { 
        include "complete"
        interpret osfLeft {
            action = RedirectKey(keycode=<LEFT>, clearmodifiers=Mod1);
        };
        interpret osfRight {
            action = RedirectKey(keycode=<RGHT>, clearmodifiers=Mod1);
        };
        interpret osfUp {
            action = RedirectKey(keycode=<UP>, clearmodifiers=Mod1);
        };
        interpret osfDown {
            action = RedirectKey(keycode=<DOWN>, clearmodifiers=Mod1);
        };
        interpret osfBeginLine {
            action = RedirectKey(keycode=<HOME>, clearmodifiers=Mod1);
        };
        interpret osfEndLine {
            action = RedirectKey(keycode=<END>, clearmodifiers=Mod1);
        };
        interpret osfPageUp {
            action = RedirectKey(keycode=<PGUP>, clearmodifiers=Mod1);
        };
        interpret osfPageDown {
            action = RedirectKey(keycode=<PGDN>, clearmodifiers=Mod1);
        };
        interpret osfDelete {
            action = RedirectKey(keycode=<DELE>, clearmodifiers=Mod1);
        };
    };
    xkb_symbols { 
        include "pc+de(nodeadkeys)"
        include "inet(evdev)"
        include "compose(rwin)"
        key <LALT> {
            type[Group1] = "ONE_LEVEL",
            symbols[Group1] = [ ISO_Level5_Shift ]
        };
        modifier_map Mod1 { <LALT> };
        key <AC07> {
            type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
            symbols[Group1] = [ j, J, dead_belowdot, dead_abovedot, osfLeft, osfLeft, osfLeft, osfLeft ]
        };
        key <AC08> {
            type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
            symbols[Group1] = [ k, K, kra, ampersand, osfDown, osfDown, osfDown, osfDown ]
        };
        key <AC09> {
            type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
            symbols[Group1] = [ l, L, lstroke, Lstroke, osfRight, osfRight, osfRight, osfRight ]
        };
        key <AC10> {
            type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
            symbols[Group1] = [ odiaeresis, Odiaeresis, doubleacute, doubleacute, osfPageDown, osfPageDown, osfPageDown, osfPageDown ]
        };
        key <AD07> {
            type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
            symbols[Group1] = [ u, U, downarrow, uparrow, osfBeginLine, osfBeginLine, osfBeginLine, osfBeginLine ]
        };
        key <AD08> {
            type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
            symbols[Group1] = [ i, I, rightarrow, idotless, osfUp, osfUp, osfUp, osfUp ]
        };
        key <AD09> {
            type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
            symbols[Group1] = [ o, O, oslash, Oslash, osfEndLine, osfEndLine, osfEndLine, osfEndLine ]
        };
        key <AD10> {
            type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
            symbols[Group1] = [ p, P, thorn, THORN, osfPageUp, osfPageUp, osfPageUp, osfPageUp ]
        };
        key <BKSP> {
            type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
            symbols[Group1] = [ BackSpace, BackSpace, BackSpace, BackSpace, osfDelete, osfDelete, osfDelete, osfDelete ] 
        };
    };
    xkb_geometry { 
        include "pc(pc105)" 
    };
};

Ho lo stesso problema. È così doloroso.

Quindi il titolo è "Come fare in modo che tutte le applicazioni rispettino il mio layout xkb modificato?". Bene, penso che l'unico modo sia riparare tutti i programmi che lo fanno in modo errato. Facciamolo!

Bene, dopo aver segnalato quel bug in NetBeans (Aggiornamento:ho provato l'ultima versione e ora funziona! ), ho pensato che avrei continuato a segnalare questo bug per ogni applicazione. L'applicazione successiva nell'elenco è stata Speedcrunch .

Tuttavia, dopo aver cercato segnalazioni di bug simili, ho riscontrato questo problema. Qualcun altro ha lo stesso problema, fantastico!

Dopo aver letto i commenti capirai che questo bug dovrebbe essere presente in tutte le app QT. Ecco una segnalazione di bug QT. Non risolto, ma ​​sembra che il problema sia stato risolto in Qt5 .

Tuttavia, se guardi i commenti, c'è una soluzione alternativa! Ecco come funziona. Se stavi facendo questo:

key <SPCE> { [ ISO_Level3_Shift ] };

Quindi puoi cambiarlo in questo:

key <SPCE> {
  type[Group1]="ONE_LEVEL",
  symbols[Group1] = [ ISO_Level3_Shift ]
};

E risolverà effettivamente il problema per alcune delle applicazioni! Ad esempio, Speedcrunch ora funziona per me! Evviva!

Riepilogo

In questo momento qualsiasi applicazione dovrebbe funzionare correttamente. In caso contrario, devi utilizzare type[Group1]="ONE_LEVEL" . Se lo hai già, devi aggiornare il tuo software. Se continua a non funzionare, è specifico dell'app e devi inviare una segnalazione di bug.

AGGIORNAMENTO (23-09-2017)

Ad oggi tutte le applicazioni rispettano il layout della mia tastiera. Tutti tranne uno.

Seriamente, la gestione della tastiera in Chromium è spazzatura . Ci sono diversi problemi con esso:

  • La selezione dello spostamento non funziona con i tasti freccia personalizzati (ma i tasti freccia stessi funzionano bene)
  • Se hai più layout e su uno dei layout qualche tasto è speciale (ad es. Frecce, Backspace, ecc.), allora su un altro layout questo tasto sarà fissato a quello che hai sul tuo primo layout. Ad esempio, se hai due layout:foo ,bar e alcuni tasti fanno Backspace in foo , quindi continuerà a funzionare come Backspace in bar anche se lì viene ridefinito.

Per anni ho ignorato questi problemi semplicemente non usando il cromo. Tuttavia, al giorno d'oggi le cose tendono a utilizzare Electron, che purtroppo è costruito su Chromium.

Il modo giusto per risolvere questo problema sarebbe inviare una segnalazione di bug in Chromium e sperare per il meglio. Non so quanto tempo impiegheranno a risolvere un problema che riguarda solo un paio di utenti... ma sembra essere l'unica via d'uscita. Il problema con questo è che il cromo in realtà funziona bene con neo(de) disposizione. Il layout Neo ha i tasti freccia al livello 5, ma non riesco a farlo funzionare nel mio layout personalizzato.

Segnalazioni di bug ancora aperte:

  • Pluma – https://github.com/mate-desktop/pluma/issues/17

Linux
  1. Come impostare le chiavi SSH

  2. Come creare un insieme completo di possibilità per definire i "personaggi di comando" dello schermo Gnu?

  3. Come ripristinare tutte le chiavi Gsettings ai loro valori predefiniti?

  4. Come elencare tutti gli utenti che hanno effettuato l'accesso

  5. Come eliminare tutte le righe di un file in Vim

Come rendere eseguibile un file in Linux

Come rendere Debian Linux più veloce

Come disinstallare le applicazioni WINE

Come rendere il mio sito Web inaccessibile a tutti i visitatori

Come rendere un utente un amministratore in Debian 11

Come fare in modo che i comandi in Mathematica 8 utilizzino tutti i core?