GNU/Linux >> Znalost Linux >  >> Linux

Jak zajistit, aby všechny aplikace respektovaly mé upravené rozvržení xkb?

Proč nefungují

Podle článku ArchWiki, který jste zmínil:

  • X server získá kódy klíčů ze vstupního zařízení a převede je dostavu a keysym .

    • stát je bitová maska ​​modifikátorů X (Ctrl/Shift/atd).

    • keysym je (podle /usr/include/X11/keysymdef.h ) celé číslo, které

      identifikovat znaky nebo funkce spojené s každou klávesou (např. pomocí viditelného gravírování) rozložení klávesnice.

      Každý tisknutelný znak má svůj vlastní klíčový symbol, například plus , a , A neboCyrillic_a , ale další klíče také generují své klíčové symboly, například Shift_L , Left nebo F1 .

  • Aplikace v událostech stisknutí/uvolnění kláves získá všechny tyto informace.

    Některé aplikace sledují klíčové symboly jako Control_L sami, ostatní jen hledají modifikační bity ve stavu .

Co se tedy stane, když stisknete AltGr +j :

  • Stisknete AltGr . Aplikace získá událost KeyPressed s keycode108 (<RALT> ) a keyym 0xfe03 (ISO_Level3_Shift ), stav je 0.

  • Stisknete j (které se v dvoraku mapuje na „h“ bez modifikátorů). Aplikace získá událost KeyPressed s kódem klíče 44 (<AC07> ), keyym 0xff51(Left ) a stav 0x80 (modifikátor Mod5 je zapnutý).

  • Uvolníte j . Aplikace získá událost KeyRelease pro klíč<AC07> /Left se stejnými parametry.

  • Poté uvolněte AltGr — Událost KeyRelease pro AltGr. (Mimochodem, stav je zde stále 0x80, ale na tom nezáleží.)

To lze vidět, když spustíte xev utility.

To vše tedy znamená, že ačkoli aplikace dostane stejný kód keyym (Left ) jako od normálního klíče <LEFT> , také získá klíčový kód a stav modifikátoru z AltGr. S největší pravděpodobností ty programy, které nefungují, sledují modifikátory a nechtějí fungovat, když jsou některé aktivní.

Jak zajistit, aby fungovaly

Zjevně nemůžeme změnit každý program na nehledat modifikátory. Jedinou možností, jak z této situace uniknout, je negenerovat klíčové symmy a stavové bity modifikátorů.

1. Samostatná skupina

Jediná metoda, která mě napadá, je:definovat klávesy pro pohyb kurzoru v samostatné skupině a přepnout se samostatným stisknutím kláves na tuto skupinu před stisknutím kláves j , k , l , i (h ,t , n , c ) (jak jsem pochopil, skupinové blokování je preferovanou metodou pro jednorázovou změnu skupiny).

Například:

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)" };
};

Nyní, když nejprve stisknete AltGr a pak (samostatně) jednu z kláves pohybu, mělo by to fungovat.

To však není příliš užitečné, vhodnější by bylo LockGroup místo latch a stiskněte AltGr před a po skupinovém přepnutí. Ještě lepší možná bude SetGroup — pak by AltGr vybral tuto skupinu pouze při stisknutí, ale to prozradí aplikacím klíčový symtom AltGr (ISO_Group_Shift /ISO_Group_Latch /cokoli je definováno) (ale stavy modifikátoru zůstávají čisté).

Ale... zbývá také možnost, že aplikace také čte kódy klíčů (kódy skutečných klíčů). Poté si všimne „falešných“ kurzorových kláves.

2. Překryv

Více „nízkoúrovňovým“ řešením by bylo překrytí (jak popisuje stejný článek).

Překryvná vrstva jednoduše znamená, že některá (skutečná klávesnice) klávesa vrací kód jiné klávesy. X server změní kód klíče klíče a vypočítá stav modifikátoru a keyym pro tento nový kód klíče, takže aplikace by si změny neměly všimnout.

Překryvné vrstvy jsou však velmi omezené:

  • Na X serveru jsou pouze 2 řídicí bity překryvů (tj. mohou být maximálně 2 překryvné vrstvy).
  • Každý klíč může mít pouze 1 alternativní kód klíče.

Pokud jde o zbytek, implementace je velmi podobná metodě s oddělenou skupinou:

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 znamená změnit řídicí bit při stisku klávesy a obnovit jej při uvolnění klávesy. Měla by existovat podobná funkce LatchControls , alexkbcomp dává mi

Error:            Unknown action LatchControls

na kompilaci mapy kláves.

(Mimochodem, také používám dvorak a také jsem přemapoval některé pohybové klávesy na vysoké úrovně abecedních kláves. A také jsem narazil na některé nefunkční funkce (výběr v poznámkách Xfce a přepínání plochy pomocí Ctrl-Alt-Left/Right). Díky za vaši otázku a tato odpověď, teď už vím, co je to překryv :).)


Jak zajistit, aby fungovaly – řešení 3

Použití dalších úrovní a Action RedirectKey

Následující řešení používá levý Alt k poskytnutí kurzorových kláves na jkli, Home/End/PageUp/PageDown na uopö a Delete na Backspace.

Levá klávesa Alt zůstává použitelná pro jiné účely pro všechny ostatní klávesy (jako pro menu aplikace). Levý Alt (Mod1) je při použití bloku kurzoru odstraněn ze stavu modifikátoru, takže jej aplikace nevidí.

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)" 
    };
};

Mám stejný problém. Je to tak bolestivé.

Název je tedy „Jak zajistit, aby všechny aplikace respektovaly mé upravené rozvržení xkb?“. No, myslím, že jediný způsob je opravit všechny programy, které to dělají špatně. Pojďme na to!

Po nahlášení této chyby v NetBeans (Aktualizace:Vyzkoušel jsem nejnovější verzi a nyní to funguje! ), Myslel jsem, že budu tuto chybu hlásit pro každou aplikaci. Další aplikací na seznamu byla aplikace Speedcrunch .

Po hledání podobných zpráv o chybách jsem však našel tento problém. Někdo jiný má stejný problém, skvělé!

Po přečtení komentářů pochopíte, že tato chyba by měla být přítomna ve všech aplikacích QT. Zde je zpráva o chybě QT. Nevyřešeno, ale zdá se, že problém je vyřešen v Qt5 .

Pokud se však podíváte na komentáře, existuje řešení! Zde je návod, jak to funguje. Pokud byste dělali toto:

key <SPCE> { [ ISO_Level3_Shift ] };

Pak to můžete změnit na toto:

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

A u některých aplikací to skutečně vyřeší problém! Například Speedcrunch teď mi to funguje! Hurá!

Shrnutí

Právě teď by měla každá aplikace fungovat správně. Pokud ne, musíte použít type[Group1]="ONE_LEVEL" . Pokud jej již máte, musíte software aktualizovat. Pokud to stále nefunguje, je to specifické pro aplikaci a musíte odeslat hlášení o chybě.

AKTUALIZACE (23. 9. 2017)

Ode dneška všechny aplikace respektují moje rozložení klávesnice. Všechny kromě jednoho.

Vážně, manipulace s klávesnicí v prohlížeči Chromium je nesmysl . Je s tím několik problémů:

  • Výběr pomocí kláves s vlastními šipkami nefunguje (ale samotné klávesy se šipkami fungují OK)
  • Pokud máte více rozvržení a na jednom z rozvržení je některá klávesa speciální (např. šipky, Backspace atd.), bude na jiném rozvržení tato klávesa pevně nastavena na to, co máte v prvním rozvržení. Máte-li například dvě rozvržení:foo ,bar a některá klávesa dělá Backspace v foo , pak bude nadále fungovat jako Backspace v bar i když je to tam předefinováno.

Po léta jsem tyto problémy ignoroval tím, že jsem prostě nepoužíval chrom. V dnešní době se však používá Electron, který je bohužel postaven na Chromiu.

Správným způsobem, jak to vyřešit, by bylo odeslat hlášení o chybě v prohlížeči Chromium a doufat v to nejlepší. Nevím, jak dlouho jim bude trvat, než vyřeší problém, který se týká pouze několika uživatelů... ale zdá se, že je to jediná cesta ven. Problém je v tom, že chrom ve skutečnosti funguje dobře s neo(de) rozložení. Rozvržení Neo má klávesy se šipkami na úrovni 5, ale nemohu ho zprovoznit ve vlastním rozvržení.

Stále otevřené zprávy o chybách:

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

Linux
  1. Jak nastavit klíče SSH

  2. Vlastní rozvržení Xkb, ve kterém klíči vytvoří dva kódové body Unicode?

  3. Jak vytvořit komplexní sadu možností pro definování „příkazových znaků“ na obrazovce Gnu?

  1. Jak resetovat všechny klíče Gsettings na jejich výchozí hodnoty?

  2. Jak vypsat všechny přihlášené uživatele

  3. Jak udělat soubor řídký?

  1. Jak zajistit, aby byl panel aktivit Gnome Shell neustále malý?

  2. jak aktualizovat homebrew pomocí Cronu na Mac OS

  3. Jak znovu načíst všechny spuštěné aplikace z odkládacího prostoru do RAM?