Compose-Kombinationen unter kbdneo2 vervollständigen #567

Open
opened 5 months ago by Rojetto · 6 comments
Rojetto commented 5 months ago

Ich habe gerade versucht das Zeichen ⊆ mit verschiedenen Compose-Variationen zu schreiben. Wie korrekt dokumentiert war ich schlussendlich mit NeoVars erfolgreich, mit kbdneo2 (meinem bevorzugten Treiber) aber nicht.

Auf die schönen Compose-Module in https://git.neo-layout.org/neo/neo-layout/src/branch/master/Compose/src scheint letzter ja zumindest nicht direkt zuzugreifen, stattdessen habe ich im C-Code eine gigantische gehardcodete Definition scheinbar aller Compose-Kombinationen gefunden.

Spricht etwas dagegen, die fehlenden Einträge einfach zu ergänzen? Oder gibt es vielleicht einen Build-Schritt, der diese automatisch generieren könnte und den ich einfach noch nicht gefunden habe?

Ich habe gerade versucht das Zeichen ⊆ mit verschiedenen Compose-Variationen zu schreiben. Wie [korrekt dokumentiert](https://git.neo-layout.org/neo/neo-layout/wiki/Tote-Tasten-und-Compose#user-content-windows) war ich schlussendlich mit NeoVars erfolgreich, mit kbdneo2 (meinem bevorzugten Treiber) aber nicht. Auf die schönen Compose-Module in https://git.neo-layout.org/neo/neo-layout/src/branch/master/Compose/src scheint letzter ja zumindest nicht direkt zuzugreifen, stattdessen habe ich im [C-Code](https://git.neo-layout.org/neo/neo-layout/src/branch/master/windows/kbdneo2/source/kbdneo2/kbdneo2.c#L468) eine gigantische gehardcodete Definition scheinbar aller Compose-Kombinationen gefunden. Spricht etwas dagegen, die fehlenden Einträge einfach zu ergänzen? Oder gibt es vielleicht einen Build-Schritt, der diese automatisch generieren könnte und den ich einfach noch nicht gefunden habe?
qwertfisch added the
Treiber/Windows/kbdneo
label 5 months ago
Owner

Die vorhandenen Compose-Kombinationen (über DEADTRANS) wurden seit sehr langer Zeit nicht mehr angefasst. Es gibt derzeit keinen automatischen Buildschritt. Um zu schauen, wie die Definitionen ursprünglich generiert wurden, müsste ich länger in alten Commits recherchieren – kurz gesagt: sie sind einfach da.

Einträge zu ergänzen wäre nicht das Problem. Ich habe beim Ausprobieren aber bemerkt, dass einige der CoKos nicht funktionieren, obwohl definiert. Beispielsweise sollte ♫/⊂ zu ⊄ führen (siehe hier), was es aber nicht tut. Stattdessen wird das „⊂“ ausgegeben, aber die Compose-Generierung nicht beendet. Es deutet darauf hin, dass gewisse Unicodes – oder aber Zeichen aus höheren Ebenen – nicht für Kombinationen verwendet werden können. Dementsprechend wirst Du mit ♫_⊂ (aus en_US.UTF-8) oder ♫=⊂ (aus math.module) wohl kein Glück haben.

Aber wo ich mir gerade die Frage stellte, wie du „⊆“ in NeoVars eingetippt hast, kam ich darauf, dass dies auf Ebene 6 auf dem Ziffernblock liegt (Taste „4“). Das ist so auch in kbdneo definiert. Ist das eine akzeptable Lösung, oder soll es unbedingt über eine Compose-Kombination (im Hauptfeld der Tastatur) einzutippen sein?

Die vorhandenen Compose-Kombinationen (über `DEADTRANS`) wurden seit sehr langer Zeit nicht mehr angefasst. Es gibt derzeit keinen automatischen Buildschritt. Um zu schauen, wie die Definitionen ursprünglich generiert wurden, müsste ich länger in alten Commits recherchieren – kurz gesagt: sie sind einfach da. Einträge zu ergänzen wäre nicht das Problem. Ich habe beim Ausprobieren aber bemerkt, dass einige der CoKos nicht funktionieren, obwohl definiert. Beispielsweise sollte `♫/⊂` zu ⊄ führen ([siehe hier](https://git.neo-layout.org/neo/neo-layout/src/branch/master/windows/kbdneo2/source/kbdneo2/kbdneo2.c#L1946)), was es aber nicht tut. Stattdessen wird das „⊂“ ausgegeben, aber die Compose-Generierung nicht beendet. Es deutet darauf hin, dass gewisse Unicodes – oder aber Zeichen aus höheren Ebenen – nicht für Kombinationen verwendet werden können. Dementsprechend wirst Du mit `♫_⊂` (aus [en_US.UTF-8](https://git.neo-layout.org/neo/neo-layout/src/branch/master/Compose/src/en_US.UTF-8#L5874)) oder `♫=⊂` (aus [math.module](https://git.neo-layout.org/neo/neo-layout/src/branch/master/Compose/src/math.module#L124)) wohl kein Glück haben. Aber wo ich mir gerade die Frage stellte, wie du „⊆“ in NeoVars eingetippt hast, kam ich darauf, dass dies auf Ebene 6 auf dem Ziffernblock liegt (Taste „4“). Das ist so auch in kbdneo definiert. Ist das eine akzeptable Lösung, oder soll es unbedingt über eine Compose-Kombination (im Hauptfeld der Tastatur) einzutippen sein?
Poster

Danke für die Recherche, hier nochmal zusammengefasst, was bei mir geht und was nicht.

„⊆“ mit <dead_macron>⊂: kbdneo gibt aus ¯⊂, neovars geht
„⊆“ mit ♫=⊂: kbdneo gibt aus =⊂, neovars gibt nichts aus
„⊄“ mit ♫/⊂: kbdneo geht, neovars geht

Da meine Tastatur keinen Ziffernblock hat, fällt die von dir vorgeschlagene Variante leider aus.

Um noch ein weiteres Fass aufzumachen: der Interrobang ‽ ♫1?! benötigt drei Zeichen nach ♫. Es sieht so aus, als ob die von Windows erwarteten Datenstrukturen so etwas überhaupt nicht erlauben.

Nur mal in den Raum gestellt, macht es vielleicht Sinn, zumindest die Compose-Funktion (wenn nicht sogar die gesamte Ebene 3 und höhere, gerade wegen Kompatibilität, siehe #510) in das AHK-Skript auszulagern, das man für Ebene 4 sowieso braucht? Der Punkt ist sicher diskutabel, aber das kommt mir deutlich besser wartbar vor, als die eingeschränkten Möglichkeiten von Windows an der Stelle so halbgar (weil an der Stelle technisch nicht besser möglich) hinzubiegen.

Danke für die Recherche, hier nochmal zusammengefasst, was bei mir geht und was nicht. „⊆“ mit `<dead_macron>⊂`: kbdneo gibt aus `¯⊂`, neovars geht „⊆“ mit `♫=⊂`: kbdneo gibt aus `=⊂`, neovars gibt nichts aus „⊄“ mit `♫/⊂`: kbdneo geht, neovars geht Da meine Tastatur keinen Ziffernblock hat, fällt die von dir vorgeschlagene Variante leider aus. Um noch ein weiteres Fass aufzumachen: der Interrobang ‽ `♫1?!` benötigt drei Zeichen nach ♫. Es sieht so aus, als ob die von Windows erwarteten Datenstrukturen so etwas überhaupt nicht erlauben. Nur mal in den Raum gestellt, macht es vielleicht Sinn, zumindest die Compose-Funktion (wenn nicht sogar die gesamte Ebene 3 und höhere, gerade wegen Kompatibilität, siehe #510) in das AHK-Skript auszulagern, das man für Ebene 4 sowieso braucht? Der Punkt ist sicher diskutabel, aber das kommt mir deutlich besser wartbar vor, als die eingeschränkten Möglichkeiten von Windows an der Stelle so halbgar (weil an der Stelle technisch nicht besser möglich) hinzubiegen.
Owner

Huch, ich wollte hierauf doch vor Tagen schon geantwortet haben.

„⊄“ mit ♫/⊂: kbdneo geht, neovars geht

In der Tat. Mein Fehler war, dass ich „⊂“ vom Ziffernblock benutzt habe, nicht von Ebene 6 im Hauptfeld. Da funktioniert es.

Es deutet darauf hin, dass gewisse Unicodes – oder aber Zeichen aus höheren Ebenen – nicht für Kombinationen verwendet werden können

Mein Gesagtes widerrufe ich daher, war eine falsche Vermutung. Somit ist das Problem nur, dass ⊆ nicht als Compose-Kombination in kbdneo definiert ist. Zur Zeit fehlen uns die nötigen Schritte, um aus den Compose-Definitionen den hartkodierten C-Code zu erzeugen. Es ist nicht ganz nachvollziehbar, welche Definitionen letztlich enthalten sind. Es sollte – wie oben verlinkt – in en_US.utf8 drin sein (über ♫_⊂), aber anscheinend kamen die erst 2012 hinzu. Die mathematischen Composes mit = oder dem Dead Macron fehlen dagegen komplett.

macht es vielleicht Sinn, zumindest die Compose-Funktion (wenn nicht sogar die gesamte Ebene 3 und höhere, gerade wegen Kompatibilität, siehe #510) in das AHK-Skript auszulagern, das man für Ebene 4 sowieso braucht?

Wenn du die ganze Ebene 3 mit auslagerst, kannst du besser gleich NeoVars nehmen … Die Probleme mit E3 liegen nicht an Composes und auch nicht am Treiber, sondern an den Programmen bzw. Frameworks wie Qt und GTK, die nicht einsehen wollen, dass sie Windows-Keyboard-Krams nicht gemäß Spezifikation nachbauen.

Über die Compose-Funktion ließe sich streiten. An sich ist die tauglich und schafft auch beliebig lange Kombinationen (auch wenn mir gerade kein Beispiel einfällt). Sie ist bislang nur nicht so einfach einzubauen für spezielle Compose-Module. Ich wäre dafür, hier die Build-Doku zu ergänzen und auch den C-Code für die Composes nachvollziehbar zu generieren.

Huch, ich wollte hierauf doch vor Tagen schon geantwortet haben. > „⊄“ mit ♫/⊂: kbdneo geht, neovars geht In der Tat. Mein Fehler war, dass ich „⊂“ vom Ziffernblock benutzt habe, nicht von Ebene 6 im Hauptfeld. Da funktioniert es. > Es deutet darauf hin, dass gewisse Unicodes – oder aber Zeichen aus höheren Ebenen – nicht für Kombinationen verwendet werden können Mein Gesagtes widerrufe ich daher, war eine falsche Vermutung. Somit ist das Problem nur, dass ⊆ nicht als Compose-Kombination in kbdneo definiert ist. Zur Zeit fehlen uns die nötigen Schritte, um aus den Compose-Definitionen den hartkodierten C-Code zu erzeugen. Es ist nicht ganz nachvollziehbar, welche Definitionen letztlich enthalten sind. Es sollte – wie oben verlinkt – in en_US.utf8 drin sein (über `♫_⊂`), aber anscheinend kamen die erst 2012 hinzu. Die mathematischen Composes mit `=` oder dem Dead Macron fehlen dagegen komplett. > macht es vielleicht Sinn, zumindest die Compose-Funktion (wenn nicht sogar die gesamte Ebene 3 und höhere, gerade wegen Kompatibilität, siehe #510) in das AHK-Skript auszulagern, das man für Ebene 4 sowieso braucht? Wenn du die ganze Ebene 3 mit auslagerst, kannst du besser gleich NeoVars nehmen … Die Probleme mit E3 liegen nicht an Composes und auch nicht am Treiber, sondern an den Programmen bzw. Frameworks wie Qt und GTK, die nicht einsehen wollen, dass sie Windows-Keyboard-Krams nicht gemäß Spezifikation nachbauen. Über die Compose-Funktion ließe sich streiten. An sich ist die tauglich und schafft auch beliebig lange Kombinationen (auch wenn mir gerade kein Beispiel einfällt). Sie ist bislang nur nicht so einfach einzubauen für spezielle Compose-Module. Ich wäre dafür, hier die Build-Doku zu ergänzen und auch den C-Code für die Composes nachvollziehbar zu generieren.
Poster

Beim Thema Ebene 3 hast du natürlich recht, grundsätzlich liegt der „Fehler“ nicht bei uns sondern bei den GUI-Frameworks. Andererseits ist es nach meiner Einschätzung nicht realistisch, dass diese das Problem zeitnah beheben und die neueste Version in allen darauf aufbauenden Anwendungen ankommt.

Mit den beliebig langen CoKos stimme ich dir zu, das hatte ich beim ersten Durchschauen nicht ganz durchdrungen. Was nach meinem Verständnis aber weiterhin nicht geht sind Zeichen außerhalb des UTF-16 Bereichs (sämtliche Emojis z. B.) oder Strings aus mehreren Zeichen.

Als Alternative zur AHK-Erweiterung habe ich deshalb ein eigenes Ergänzungsprogramm geschrieben, das für meine Anwendungen diese Sachen behebt: https://github.com/Rojetto/ReNeo

Die CoKos werden beim Start direkt aus den .module-Dateien geladen und müssen nicht kompiliert werden. Außerdem gibt es ein paar Worarounds für die anderen kbdneo-Inkompatibilitäten #510 und #397. Ich hoffe jemand anderes kann ebenfalls etwas damit anfangen.

Beim Thema Ebene 3 hast du natürlich recht, grundsätzlich liegt der „Fehler“ nicht bei uns sondern bei den GUI-Frameworks. Andererseits ist es nach meiner Einschätzung nicht realistisch, dass diese das Problem zeitnah beheben und die neueste Version in allen darauf aufbauenden Anwendungen ankommt. Mit den beliebig langen CoKos stimme ich dir zu, das hatte ich beim ersten Durchschauen nicht ganz durchdrungen. Was nach meinem Verständnis aber weiterhin nicht geht sind Zeichen außerhalb des UTF-16 Bereichs (sämtliche Emojis z. B.) oder Strings aus mehreren Zeichen. Als Alternative zur AHK-Erweiterung habe ich deshalb ein eigenes Ergänzungsprogramm geschrieben, das für meine Anwendungen diese Sachen behebt: https://github.com/Rojetto/ReNeo Die CoKos werden beim Start direkt aus den `.module`-Dateien geladen und müssen nicht kompiliert werden. Außerdem gibt es ein paar Worarounds für die anderen kbdneo-Inkompatibilitäten #510 und #397. Ich hoffe jemand anderes kann ebenfalls etwas damit anfangen.
Owner

Danke für deine Bemühungen und den neuen Ansatz für einen funktionsfähigen Tastaturtreiber. In dieser Form gab es noch keinen Versuch. Prinzipiell lagerst du mehr Features in den Usermode-Anteil aus, ohne den nativen Treiber komplett wegzulassen (wie bei NeoVars bzw. neo2-llkh). Die Basisebenen – bis auf E4-Steuertasten – funktionieren ja weiterhin über kbdneo.

Ich finde, diese Idee sollte man weiterverfolgen. Für Compose selbst gibt es zwar nur den Vorteil, dass Zeichen > U+10000 erzeugt werden können – wobei ich auch gerade nicht weiß, wie Windows damit grundsätzlich umgeht. UTF-16 bedeutet nicht, dass nur ein Teil von Unicode genutzt wird, sondern dass man mit Low/High Surrogates arbeiten und zwei Zeichen erzeugen müsste. Vermutlich klappt es daher nicht über den nativen Treiber.
Dafür handhabt ReNeo die ganze Ebene3 und Mod3+Tab so, dass es mit allen anderen Programmen funktioniert (äquivalent zu NeoVars/neo2-llkh). Das dynamische Laden von Compose-Kombinationen ist ebenfalls herausragend. 👍

Fragen

Wie funktioniert die Ersetzung, immerhin ist kbdneo nicht umgebaut und erzeugt seinerseits CoKos und Diakritika über Tottasten. Wie wird verhindert, dass diese dann nicht erscheinen, sondern nur die in ReNeo definierten (über die Moduldateien)? Gleiche Frage auch für Zeichen aus Ebene 3.

Wie stellen sich Mod3-Kombinationen für andere Programme dar? kbdneo bietet als natives Layout den Vorteil, dass man z.B. in Computerspielen bei der Konfiguration direkt sieht, dass eine Taste „Mod3“ heißt und nicht „Capslock“. Hast du es in Spielen getestet, also werden da auch keine Geisterzeichen erzeugt, wenn man z.B. seine Spielfigur mit Mod3 und anderen Tasten steuert?

Vielleicht magst du bei Gelegenheit in den Neo-Chat kommen. Das wäre ein besserer Platz als hier zum Diskutieren. Bin da immer erreichbar (außer donnerstag nachmittags).

Danke für deine Bemühungen und den neuen Ansatz für einen funktionsfähigen Tastaturtreiber. In dieser Form gab es noch keinen Versuch. Prinzipiell lagerst du mehr Features in den Usermode-Anteil aus, ohne den nativen Treiber komplett wegzulassen (wie bei NeoVars bzw. neo2-llkh). Die Basisebenen – bis auf E4-Steuertasten – funktionieren ja weiterhin über kbdneo. Ich finde, diese Idee sollte man weiterverfolgen. Für Compose selbst gibt es zwar nur den Vorteil, dass Zeichen > U+10000 erzeugt werden können – wobei ich auch gerade nicht weiß, wie Windows damit grundsätzlich umgeht. UTF-16 bedeutet nicht, dass nur ein Teil von Unicode genutzt wird, sondern dass man mit Low/High Surrogates arbeiten und zwei Zeichen erzeugen müsste. Vermutlich klappt es daher nicht über den nativen Treiber. Dafür handhabt ReNeo die ganze Ebene3 und Mod3+Tab so, dass es mit allen anderen Programmen funktioniert (äquivalent zu NeoVars/neo2-llkh). Das dynamische Laden von Compose-Kombinationen ist ebenfalls herausragend. :thumbsup: ### Fragen Wie funktioniert die Ersetzung, immerhin ist kbdneo nicht umgebaut und erzeugt _seinerseits_ CoKos und Diakritika über Tottasten. Wie wird verhindert, dass diese dann nicht erscheinen, sondern nur die in ReNeo definierten (über die Moduldateien)? Gleiche Frage auch für Zeichen aus Ebene 3. Wie stellen sich Mod3-Kombinationen für andere Programme dar? kbdneo bietet als natives Layout den Vorteil, dass man z.B. in Computerspielen bei der Konfiguration direkt sieht, dass eine Taste „Mod3“ heißt und nicht „Capslock“. Hast du es in Spielen getestet, also werden da auch keine Geisterzeichen erzeugt, wenn man z.B. seine Spielfigur mit Mod3 und anderen Tasten steuert? Vielleicht magst du bei Gelegenheit in den Neo-Chat kommen. Das wäre ein besserer Platz als hier zum Diskutieren. Bin da immer erreichbar (außer donnerstag nachmittags).
Poster

Freut mich, dass dir der Ansatz gefällt. Das Prinzip hast du genau richtig verstanden, mMn ist so eine Hybrid-Version tatsächlich etwas schwer zu erklären.

Zu deinen Fragen:

UTF-16 bedeutet nicht, dass nur ein Teil von Unicode genutzt wird, sondern dass man mit Low/High Surrogates arbeiten und zwei Zeichen erzeugen müsste. Vermutlich klappt es daher nicht über den nativen Treiber.

Natürlich bedeutet UTF-16 keine grundsätzliche Einschränkung der Zeichen, nur in der nativen Datenstruktur ist nach meiner Auffassung nur Platz für einen UTF-16 Char. In ReNEO wandle ich Strings und Zeichen der höheren Bereiche in die entsprechenden UTF-16 Blöcke um und sende sie nacheinander, so dass sie als Ganzes in der Anwendung ankommen.

Wie funktioniert die Ersetzung, immerhin ist kbdneo nicht umgebaut und erzeugt seinerseits CoKos und Diakritika über Tottasten. Wie wird verhindert, dass diese dann nicht erscheinen, sondern nur die in ReNeo definierten (über die Moduldateien)? Gleiche Frage auch für Zeichen aus Ebene 3.

Genau wie neo2-llkh nutzt ReNeo einen LowLevelKeyboardHook. Dieser lauscht mit, wann für ihn relevante Keydown-Events kommen, und schluckt diese weg um sie sofort (oder später im Falle von CoKos) mit seinen eigenen Tastendrücken zu ersetzen.

Die WM_DEADCHAR und WM_CHAR Nachrichten für Buchstaben mit Diakritika werden in den Anwendungen erst von der WindowProc erzeugt, nachdem vorher die entsprechenden WM_KEYDOWNs empfangen wurden. Fängt man letztere weg, kriegt die Anwendung auch von den toten Tasten nichts mit.

kbdneo bietet als natives Layout den Vorteil, dass man z.B. in Computerspielen bei der Konfiguration direkt sieht, dass eine Taste „Mod3“ heißt und nicht „Capslock“.

Die Namen der Tasten werden ja vom nativen Layout bereitgestellt. An denen manipuliere ich nichts, wenn es mit kbdneo geht sollte es weiterhin gehen. Hab aber auch nicht wirklich ein Beispiel zum Testen.

Hast du es in Spielen getestet, also werden da auch keine Geisterzeichen erzeugt, wenn man z.B. seine Spielfigur mit Mod3 und anderen Tasten steuert?

Ich hab es gerade in Factorio getestet und keine Probleme gefunden. Ebene 3, Tottasten und Compose gehen alle. Mod3-Kombinationen und CoKo-Ergebnisse sieht die Anwendung nur als WM_KEYDOWN/WM_KEYUP mit dem Tastencode VK_PACKET und dem fertigen Unicode-Zeichen. Von den tatsächlich dafür benötigten Anschlägen sieht sie nichts.

Im IRC kann ich gerne bei Gelegenheit vorbeischauen :)

Freut mich, dass dir der Ansatz gefällt. Das Prinzip hast du genau richtig verstanden, mMn ist so eine Hybrid-Version tatsächlich etwas schwer zu erklären. Zu deinen Fragen: > UTF-16 bedeutet nicht, dass nur ein Teil von Unicode genutzt wird, sondern dass man mit Low/High Surrogates arbeiten und zwei Zeichen erzeugen müsste. Vermutlich klappt es daher nicht über den nativen Treiber. Natürlich bedeutet UTF-16 keine grundsätzliche Einschränkung der Zeichen, nur in der nativen Datenstruktur ist nach meiner Auffassung nur Platz für einen UTF-16 Char. In ReNEO wandle ich Strings und Zeichen der höheren Bereiche in die entsprechenden UTF-16 Blöcke um und sende sie nacheinander, so dass sie als Ganzes in der Anwendung ankommen. > Wie funktioniert die Ersetzung, immerhin ist kbdneo nicht umgebaut und erzeugt seinerseits CoKos und Diakritika über Tottasten. Wie wird verhindert, dass diese dann nicht erscheinen, sondern nur die in ReNeo definierten (über die Moduldateien)? Gleiche Frage auch für Zeichen aus Ebene 3. Genau wie neo2-llkh nutzt ReNeo einen LowLevelKeyboardHook. Dieser lauscht mit, wann für ihn relevante Keydown-Events kommen, und schluckt diese weg um sie sofort (oder später im Falle von CoKos) mit seinen eigenen Tastendrücken zu ersetzen. Die WM_DEADCHAR und WM_CHAR Nachrichten für Buchstaben mit Diakritika werden in den Anwendungen erst von der WindowProc erzeugt, nachdem vorher die entsprechenden WM_KEYDOWNs empfangen wurden. Fängt man letztere weg, kriegt die Anwendung auch von den toten Tasten nichts mit. > kbdneo bietet als natives Layout den Vorteil, dass man z.B. in Computerspielen bei der Konfiguration direkt sieht, dass eine Taste „Mod3“ heißt und nicht „Capslock“. Die Namen der Tasten werden ja vom nativen Layout bereitgestellt. An denen manipuliere ich nichts, wenn es mit kbdneo geht sollte es weiterhin gehen. Hab aber auch nicht wirklich ein Beispiel zum Testen. > Hast du es in Spielen getestet, also werden da auch keine Geisterzeichen erzeugt, wenn man z.B. seine Spielfigur mit Mod3 und anderen Tasten steuert? Ich hab es gerade in Factorio getestet und keine Probleme gefunden. Ebene 3, Tottasten und Compose gehen alle. Mod3-Kombinationen und CoKo-Ergebnisse sieht die Anwendung nur als WM_KEYDOWN/WM_KEYUP mit dem Tastencode VK_PACKET und dem fertigen Unicode-Zeichen. Von den tatsächlich dafür benötigten Anschlägen sieht sie nichts. Im IRC kann ich gerne bei Gelegenheit vorbeischauen :)
Sign in to join this conversation.
Loading…
There is no content yet.