GNU/Linux >> Tutoriels Linux >  >> Linux

Comment faire en sorte que toutes les applications respectent ma mise en page xkb modifiée ?

Pourquoi ne fonctionnent-ils pas ?

D'après l'article d'ArchWiki que vous avez mentionné :

  • Le serveur X obtient les codes clés du périphérique d'entrée et les convertit à l'état et keysym .

    • état est le masque de bits des modificateurs X (Ctrl/Maj/etc).

    • keysym est (selon /usr/include/X11/keysymdef.h ) l'entier qui

      identifier les caractères ou les fonctions associées à chaque touche (par exemple, via la gravure visible) d'une disposition de clavier.

      Chaque caractère imprimable a son propre keysym, comme plus , a , A , ouCyrillic_a , mais d'autres clés génèrent également leurs keysyms, comme Shift_L , Left ou F1 .

  • L'application dans les événements clés de presse/libération obtient toutes ces informations.

    Certaines applications suivent les keysyms comme Control_L par eux-mêmes, d'autres recherchent simplement les bits de modification dans l'état .

Alors que se passe-t-il lorsque vous appuyez sur AltGr +j :

  • Vous appuyez sur AltGr . L'application obtient l'événement KeyPressed avec keycode108 (<RALT> ) et keysym 0xfe03 (ISO_Level3_Shift ), l'état est 0.

  • Vous appuyez sur j (qui correspond à "h" dans dvorak sans modificateurs). L'application obtient l'événement KeyPressed avec le code clé 44 (<AC07> ), keysym 0xff51(Left ) et l'état 0x80 (le modificateur Mod5 est activé).

  • Vous relâchez j . L'application obtient l'événement KeyRelease pour la clé<AC07> /Left avec les mêmes paramètres.

  • Relâchez ensuite AltGr — Événement KeyRelease pour AltGr. (Au fait, l'état ici est toujours 0x80, mais cela n'a pas d'importance.)

Cela peut être vu si vous exécutez xev utilitaire.

Donc, tout cela signifie que, bien que l'application obtienne le même code keysym (Left ) à partir de la clé normale <LEFT> , il obtient également le code keysym et l'état du modificateur de l'AltGr. Très probablement, ces programmes qui ne fonctionnent pas surveillent les modificateurs et ne veulent pas fonctionner lorsque certains sont actifs.

Comment les faire fonctionner

Apparemment, nous ne pouvons pas modifier chaque programme pour ne pas rechercher de modificateurs. Alors la seule option pour échapper à cette situation est de ne pas générer les keysyms et les bits d'état des modificateurs.

1. Groupe séparé

La seule méthode qui me vient à l'esprit est la suivante :définir les touches de déplacement du curseur dans un groupe séparé et basculer, avec une touche distincte, vers ce groupe avant d'appuyer sur les touches j , k , l , je (h ,t , n , c ) (le verrouillage de groupe est la méthode préférée pour un changement de groupe ponctuel, si j'ai bien compris).

Par exemple :

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

Maintenant, si vous appuyez d'abord sur AltGr puis (séparément) une des touches de déplacement, cela devrait fonctionner.

Cependant, ce n'est pas très utile, il serait plus approprié de LockGroup au lieu de verrouiller et appuyez sur AltGr avant et après le changement de groupe. Encore mieux peut-être à SetGroup - alors AltGr sélectionnerait ce groupe uniquement lorsqu'il est pressé, mais cela divulgue aux applications le keysym(ISO_Group_Shift /ISO_Group_Latch /tout ce qui est défini) (mais l'état du modificateur reste propre).

Mais... il reste aussi une possibilité que l'application lise également les codes clés (les codes des vraies clés). Ensuite, il remarquera les "fausses" touches de curseur.

2. Superposition

La solution la plus "de bas niveau" serait la superposition (comme le décrit le même article).

Superposition signifie simplement qu'une touche (du clavier réel) renvoie le code d'une autre touche. Le serveur X modifie le code clé d'une clé et calcule l'état du modificateur et le keysym pour ce nouveau code clé, de sorte que l'application ne devrait pas remarquer le changement.

Mais les superpositions sont très limitées :

  • Il n'y a que 2 bits de contrôle de superposition dans le serveur X (c'est-à-dire qu'il peut y avoir un maximum de 2 superpositions).
  • Chaque clé ne peut avoir qu'un seul code clé alternatif.

Pour le reste, l'implémentation est assez similaire à la méthode avec un groupe à part :

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 signifie changer le bit de contrôle pendant que la touche est enfoncée et le restaurer au relâchement de la touche. Il devrait y avoir une fonction similaire LatchControls , maisxkbcomp me donne

Error:            Unknown action LatchControls

sur la compilation du keymap.

(Au fait, j'utilise également dvorak et j'ai également remappé certaines touches de mouvement à des niveaux élevés de touches alphabétiques. Et j'ai également rencontré des fonctionnalités cassées (sélection dans les notes Xfce et commutateur de bureau par Ctrl-Alt-Gauche/Droite). Merci à votre question et cette réponse, maintenant je sais ce qu'est une superposition :).)


Comment les faire fonctionner - Solution 3

Utilisation de niveaux supplémentaires et d'action RedirectKey

La solution suivante utilise la touche Alt gauche pour fournir des touches de curseur sur jkli, Home/End/PageUp/PageDown sur uopö et une suppression sur le retour arrière.

La touche Alt gauche reste utilisable à d'autres fins pour toutes les autres touches (comme pour le menu de l'application). L'Alt gauche (Mod1) est supprimé de l'état du modificateur lorsque le bloc curseur est utilisé afin que les applications ne puissent pas le voir.

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

J'ai le même problème. C'est tellement douloureux.

Le titre est donc "Comment faire en sorte que toutes les applications respectent ma mise en page xkb modifiée ?". Eh bien, je pense que le seul moyen est de corriger tous les programmes qui le font de manière incorrecte. Allons-y !

Eh bien, après avoir signalé ce bogue dans NetBeans (Mise à jour :j'ai essayé la dernière version et elle fonctionne maintenant ! ), j'ai pensé que je continuerai à signaler ce bogue pour chaque application. L'application suivante sur la liste était Speedcrunch .

Cependant, après avoir recherché des rapports de bogues similaires, j'ai trouvé ce problème. Quelqu'un d'autre a le même problème, super !

Après avoir lu les commentaires, vous comprendrez que ce bogue devrait être présent dans toutes les applications QT. Voici un rapport de bogue QT. Non résolu, mais il semble que le problème soit résolu dans Qt5 .

Cependant, si vous regardez les commentaires, il existe une solution de contournement ! Voici comment cela fonctionne. Si vous faisiez ceci :

key <SPCE> { [ ISO_Level3_Shift ] };

Ensuite, vous pouvez le remplacer par ceci :

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

Et cela résoudra en fait le problème pour certaines applications ! Par exemple, Speedcrunch fonctionne maintenant pour moi! Youpi !

Résumé

À l'heure actuelle, toute application devrait fonctionner correctement. Si ce n'est pas le cas, vous devez utiliser type[Group1]="ONE_LEVEL" . Si vous l'avez déjà, vous devez mettre à jour votre logiciel. Si cela ne fonctionne toujours pas, cela est spécifique à l'application et vous devez soumettre un rapport de bogue.

MISE À JOUR (2017-09-23)

A ce jour, toutes les applications respectent la disposition de mon clavier. Tous sauf un.

Sérieusement, la gestion du clavier dans Chromium est une poubelle . Il y a plusieurs problèmes avec :

  • Maj sélection ne fonctionne pas avec les touches fléchées personnalisées (mais les touches fléchées elles-mêmes fonctionnent correctement)
  • Si vous avez plusieurs mises en page et que sur l'une des mises en page, une touche est spéciale (par exemple, flèches, retour arrière, etc.), alors sur une autre mise en page, cette touche sera fixée à ce que vous avez sur votre première mise en page. Par exemple, si vous avez deux mises en page :foo ,bar et une touche fait un retour arrière en foo , il continuera alors à fonctionner comme retour arrière dans bar même s'il y est redéfini.

Pendant des années, j'ai ignoré ces problèmes en n'utilisant tout simplement pas de chrome. Cependant, de nos jours, les choses ont tendance à utiliser Electron, qui est malheureusement construit sur Chromium.

La bonne façon de résoudre ce problème serait de soumettre un rapport de bogue dans Chromium et d'espérer le meilleur. Je ne sais pas combien de temps il leur faudra pour résoudre un problème qui n'affecte que quelques utilisateurs… mais cela semble être la seule issue. Le problème avec ceci est que le chrome fonctionne bien avec neo(de) disposition. La mise en page Neo a des touches fléchées au niveau 5, mais je n'arrive pas à la faire fonctionner dans ma mise en page personnalisée.

Rapports de bugs encore ouverts :

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

Linux
  1. Comment configurer des clés SSH

  2. Disposition Xkb personnalisée dans laquelle une clé crée deux points de code Unicode ?

  3. Comment créer un ensemble complet de possibilités pour définir les "caractères de commande" de l'écran GNU ?

  4. Comment supprimer toutes les lignes d'un fichier dans Vim

  5. comment mettre à jour homebrew avec Cron sur Mac os

Comment rendre un fichier exécutable sous Linux

Comment rendre Debian Linux plus rapide

Comment désinstaller les applications WINE

Comment rendre mon site Web inaccessible à tous les visiteurs

Comment faire d'un utilisateur un administrateur dans Debian 11

Comment faire en sorte que les commandes de Mathematica 8 utilisent tous les cœurs ?