Warum funktionieren sie nicht
Laut dem Artikel von ArchWiki, den Sie erwähnt haben:
-
X-Server erhält Schlüsselcodes vom Eingabegerät und wandelt sie in den Zustand um und keysym .
-
Zustand ist die Bitmaske der X-Modifikatoren (Strg/Shift/etc).
-
keysym ist (gemäß
/usr/include/X11/keysymdef.h
) die Ganzzahl, dieIdentifizieren Sie Zeichen oder Funktionen, die jeder Taste (z. B. über die sichtbare Gravur) eines Tastaturlayouts zugeordnet sind.
Jedes druckbare Zeichen hat sein eigenes Keysym, wie
plus
,a
,A
, oderCyrillic_a
, aber auch andere Schlüssel erzeugen ihre Keysyms, wieShift_L
,Left
oderF1
.
-
-
Die Anwendung erhält alle diese Informationen in den Tastendrücken/-loslassen-Ereignissen.
Einige Anwendungen verfolgen Keysyms wie
Control_L
selbst, andere suchen einfach nach den Modifikatorbits im Zustand .
Was passiert also, wenn Sie AltGr drücken? +j :
-
Sie drücken AltGr . Anwendung erhält KeyPressed-Ereignis mit keycode108 (
<RALT>
) und keysym 0xfe03 (ISO_Level3_Shift
), Zustand ist 0. -
Sie drücken j (was in Dvorak ohne Modifikatoren auf „h“ abgebildet wird). Die Anwendung erhält das KeyPressed-Ereignis mit dem Tastencode 44 (
<AC07>
). ), keysym 0xff51(Left
) und Zustand 0x80 (Modifizierer Mod5 ist an). -
Sie geben j frei . Die Anwendung erhält das KeyRelease-Ereignis für den Schlüssel
<AC07>
/Left
mit denselben Parametern. -
Lassen Sie dann AltGr los — KeyRelease-Ereignis für AltGr. (Zustand ist hier übrigens immer noch 0x80, aber das macht nichts.)
Dies kann gesehen werden, wenn Sie xev
ausführen Dienstprogramm.
Das bedeutet also alles, obwohl die Anwendung denselben Keysym-Code (Left
) ab dem normalen Schlüssel <LEFT>
, erhält es auch den Keysym-Code und den Modifikatorstatus von AltGr. Höchstwahrscheinlich beobachten die Programme, die nicht funktionieren, die Modifikatoren und wollen nicht funktionieren, wenn einige aktiv sind.
Wie man sie zum Laufen bringt
Anscheinend können wir nicht jedes Programm so ändern, dass es nicht nach Modifikatoren sucht. Dann besteht die einzige Möglichkeit, dieser Situation zu entkommen, darin, die Keysymsand-Zustandsbits der Modifikatoren nicht zu generieren.
1. Separate Gruppe
Die einzige Methode, die mir einfällt, ist:Definieren Sie Cursorbewegungstasten in einer separaten Gruppe und wechseln Sie mit einem separaten Tastendruck zu dieser Gruppe, bevor Sie die Tasten j drücken , k , l , i (h
,t
, n
, c
) (Gruppenverriegelung ist die bevorzugte Methode für einen einmaligen Gruppenwechsel, soweit ich weiß).
Zum Beispiel:
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)" };
};
Nun, wenn Sie zuerst AltGr drücken und dann (separat) eine der Bewegungstasten, das sollte funktionieren.
Dies ist jedoch nicht sehr sinnvoll, passender wäre LockGroup
statt zu verriegeln und AltGr vor und nach dem Gruppenwechsel zu drücken. Noch besser vielleicht zu SetGroup
– dann würde AltGr diese Gruppe nur auswählen, während sie gedrückt wird, aber das offenbart den Anwendungen AltGrs keysym(ISO_Group_Shift
/ISO_Group_Latch
/was auch immer definiert ist) (aber Modifikatorzustände bleiben sauber).
Aber ... es besteht auch die Möglichkeit, dass die Anwendung auch Schlüsselcodes (die Codes der echten Schlüssel) liest. Dann bemerkt es die „falschen“ Cursortasten.
2. Überlagerung
Die eher „low-level“ Lösung wäre das Overlay (wie im gleichen Artikel beschrieben).
Überlagern bedeutet einfach, dass eine (echte) Taste den Tastencode einer anderen Taste zurückgibt. Der X-Server ändert den Keycode einer Taste und berechnet den Modifikatorstatus und das Keysym für diesen neuen Keycode, sodass die Anwendung die Änderung nicht bemerken sollte.
Aber Overlays sind sehr begrenzt:
- Es gibt nur 2 Overlay-Steuerbits im X-Server (d.h. es kann maximal 2 Overlays geben).
- Jeder Schlüssel kann nur 1 alternativen Schlüsselcode haben.
Im Übrigen ist die Implementierung der Methode mit einer separaten Gruppe sehr ähnlich:
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
bedeutet, das Steuerbit zu ändern, während die Taste gedrückt wird, und es beim Loslassen der Taste wiederherzustellen. Es sollte eine ähnliche Funktion LatchControls
geben , aberxkbcomp
gibt mir
Error: Unknown action LatchControls
bei der Keymap-Kompilierung.
(Übrigens verwende ich auch dvorak und habe auch einige Bewegungs-Keysyms auf hohe Ebenen alphabetischer Tasten neu zugeordnet. Und bin auch auf einige kaputte Funktionen gestoßen (Auswahl in Xfce-Notizen und Desktop-Wechsel durch Strg-Alt-Links/Rechts). Vielen Dank für Ihre Frage und diese Antwort, jetzt weiß ich, was ein Overlay ist :).)
Wie man sie zum Laufen bringt - Lösung 3
Zusätzliche Ebenen und Aktions-Umleitungsschlüssel verwenden
Die folgende Lösung verwendet die linke Alt-Taste, um die Cursortasten auf jkli, Home/End/PageUp/PageDown auf uopö und eine Entf-Taste auf der Rücktaste bereitzustellen.
Die linke Alt-Taste bleibt für andere Zwecke für alle anderen Tasten nutzbar (wie für das Anwendungsmenü). Die linke Alt-Taste (Mod1) wird aus dem Modifikator-Status entfernt, wenn der Cursor-Block verwendet wird, sodass Anwendungen ihn nicht sehen können.
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)"
};
};
Ich habe das gleiche Problem. Es ist so schmerzhaft.
Der Titel lautet also „Wie kann ich dafür sorgen, dass alle Anwendungen mein modifiziertes xkb-Layout berücksichtigen?“. Nun, ich denke, der einzige Weg ist, alle Programme zu reparieren, die es falsch machen. Machen wir das!
Nun, nachdem ich diesen Fehler in NetBeans gemeldet habe (Update:Ich habe die neueste Version ausprobiert und sie funktioniert jetzt! ), dachte ich, dass ich diesen Fehler einfach weiterhin für jede Anwendung melden werde. Die nächste Anwendung auf der Liste war Speedcrunch .
Nachdem ich jedoch nach ähnlichen Fehlerberichten gesucht hatte, fand ich dieses Problem. Jemand anderes hat das gleiche Problem, großartig!
Nachdem Sie die Kommentare gelesen haben, werden Sie verstehen, dass dieser Fehler in allen QT-Apps vorhanden sein sollte. Hier ist ein QT-Fehlerbericht. Nicht gelöst, aber anscheinend ist das Problem in Qt5 gelöst .
Wenn Sie sich jedoch die Kommentare ansehen, gibt es eine Problemumgehung! So funktioniert es. Wenn Sie dies getan haben:
key <SPCE> { [ ISO_Level3_Shift ] };
Dann können Sie es wie folgt ändern:
key <SPCE> {
type[Group1]="ONE_LEVEL",
symbols[Group1] = [ ISO_Level3_Shift ]
};
Und es wird das Problem für einige der Anwendungen tatsächlich lösen! Zum Beispiel Speedcrunch funktioniert jetzt bei mir! Juhu!
Zusammenfassung
Im Moment sollte jede Anwendung korrekt funktionieren. Ist dies nicht der Fall, müssen Sie type[Group1]="ONE_LEVEL"
verwenden . Wenn Sie es bereits haben, müssen Sie Ihre Software aktualisieren. Wenn es immer noch nicht funktioniert, ist es App-spezifisch und Sie müssen einen Fehlerbericht einreichen.
UPDATE (2017-09-23)
Ab heute respektieren alle Anwendungen mein Tastaturlayout. Alle außer einem.
Ernsthaft, die Handhabung der Tastatur in Chromium ist Müll . Es gibt mehrere Probleme damit:
- Die Umschaltauswahl funktioniert nicht mit benutzerdefinierten Pfeiltasten (aber die Pfeiltasten selbst funktionieren gut)
- Wenn Sie mehrere Layouts haben und auf einem der Layouts eine spezielle Taste ist (z. B. Pfeile, Rücktaste usw.), dann wird diese Taste auf einem anderen Layout auf das festgelegt, was Sie auf Ihrem ersten Layout haben. Wenn Sie beispielsweise zwei Layouts haben:
foo
,bar
und einige Tasten machen Backspace infoo
, dann funktioniert es weiterhin als Backspace inbar
auch wenn es dort umdefiniert wird.
Jahrelang habe ich diese Probleme ignoriert, indem ich einfach kein Chrom verwendet habe. Heutzutage verwenden die Dinge jedoch eher Electron, das leider auf Chromium basiert.
Der richtige Weg, dies zu lösen, wäre, einen Fehlerbericht in Chromium einzureichen und das Beste zu hoffen. Ich weiß nicht, wie lange sie brauchen werden, um ein Problem zu lösen, das nur ein paar Benutzer betrifft … aber das scheint der einzige Ausweg zu sein. Das Problem dabei ist, dass Chrom tatsächlich gut mit neo(de)
funktioniert Layout. Das Neo-Layout hat Pfeiltasten auf Level 5, aber ich kann es in meinem benutzerdefinierten Layout nicht zum Laufen bringen.
Noch offene Fehlerberichte:
- Pluma – https://github.com/mate-desktop/pluma/issues/17