Document the layout fix and the return of the title bar

AGENTS.md: die WinAPI-Regel praeziser gefasst -- verboten bleiben
Fenstermanipulation und globale Hooks, passive Layout-Abfragen sind es
nicht (und die offizielle VersaGUI macht dasselbe). Dazu die neue
Aufloesungsreihenfolge samt Warnung, nicht auf "Zeichen auswerten"
zurueckzubauen, die Kollisionsregel bei Tastennamen, der Mehrmonitor-Fix
und die Folgen der Titelleiste (welche Eigenbauten dadurch entfallen sind
und warum randlos nicht ohne Ruecksprache zurueckkommt).

README.md und docs/architecture.md entsprechend: Position statt Zeichen,
layoutrichtige Beschriftungen inkl. der Anzeigeaenderung an bestehenden
Belegungen, Taskleisten-Eintrag statt randlosem Fenster.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Julian Appel 2026-08-29 01:02:18 +02:00
parent e1e3d0e466
commit 78e9640dec
3 changed files with 152 additions and 61 deletions

View file

@ -155,27 +155,57 @@ Drei Checkboxen, unabhängig voneinander:
| Live-Sync | Fragt per Serial das aktuell aktive Profil ab, schaltet die Ansicht mit | Hintergrund-Thread pollt `read_active_profile()`, hält dafür den COM-Port dauerhaft offen, solange die Checkbox an ist. Schließt sich mit VersaGUI/Programmiermodus/MCP-Board-Zugriff gegenseitig aus (exklusiver Port). |
| Programmiermodus | Zellen anklicken zum Bearbeiten | Lädt `self.combined` **einmalig pro Prozesslauf** beim ersten Aktivieren (bevorzugt `DEFAULT_PATH`, sonst `default_combined()`). Jede Bearbeitung speichert sofort automatisch (`_autosave_combined()`). **Achtung:** Da der Snapshot nur einmal geladen wird, sieht der Programmiermodus externe Änderungen (z.B. per MCP) erst nach einem Neustart der exe oder einem expliziten „Datei laden…“. |
### Grenzen der Tastendruck-Erkennung
### Tastendruck-Erkennung: Position statt Zeichen
Die Erkennung im Bearbeiten-Dialog nutzt ausschließlich Tk-Events des
fokussierten Fensters. Daraus folgt zweierlei, und beides ist bewusst so:
fokussierten Fensters — kein globaler `SetWindowsHookEx`-Hook (siehe
`AGENTS.md`). Erste Folge: **nur was das Fenster erreicht, wird erkannt.**
Win+L, Strg+Alt+Entf und andere vom Betriebssystem abgefangene
Kombinationen kommen nie an.
1. **Nur was das Fenster erreicht, wird erkannt.** Win+L, Strg+Alt+Entf und
andere vom Betriebssystem abgefangene Kombinationen kommen nie an. Ein
globaler `SetWindowsHookEx`-Hook würde sie sehen, ist aber ausgeschlossen
(AV-Fehlalarm-Risiko, siehe `AGENTS.md`).
2. **Die Zuordnung ist eine US-Layout-Näherung.** HID-Keycodes bezeichnen
physische Tastenpositionen des US-Layouts; Tk liefert nur `keysym` und
Windows-Virtual-Key-Code, beide vom *aktiven* Layout abgeleitet. Die
physische Position (Scan-Code) wäre nötig, um das exakt aufzulösen, und
ist ohne WinAPI-Aufruf nicht verfügbar. Praktische Folge auf deutschem
Layout: Y und Z landen vertauscht auf dem Board. Das Ergebnis wird immer
ins Dropdown und in die Modifier-Checkboxen geschrieben und ist dort
korrigierbar — die Erkennung ersetzt die manuelle Auswahl nicht, sie
beschleunigt sie nur.
Zweite und wichtigere Folge betrifft die *Zuordnung*. HID-Keycodes
bezeichnen **physische Tastenpositionen**: das Board sendet eine Position,
erst Windows macht daraus über das aktive Layout ein Zeichen. Wer die
Zuordnung über das *Zeichen* aufbaut, dreht diese Kette falsch herum — auf
deutschem Layout landete dadurch jedes Y auf der Z-Taste des Boards und
ÄÖÜ/#/+ waren gar nicht erfassbar. `versapad_data.tk_event_to_hid()` löst
deshalb in dieser Reihenfolge auf:
Details der Zuordnungstabellen: `versapad_data.tk_event_to_hid()` und die
`_TK_*`/`_WIN_VK_TO_HID`-Dicts darüber.
1. **Benannte Tasten über den Tk-keysym** (Enter, Escape, Pfeile, F-Tasten,
Numpad, Entf …). Layoutunabhängig eindeutig — und hier zwingend, weil
`MapVirtualKeyW` für die Pfeiltasten denselben Scan-Code liefert wie für
ihre Numpad-Zwillinge (gemessen: VK_LEFT und VK_NUMPAD4 beide 0x4B).
2. **Zeichentasten über die physische Position**
`versapad_keylayout.hid_for_vk()`: Virtual-Key → Scan-Code
(`MapVirtualKeyW`) → HID über die layoutunabhängige Tabelle
`SCANCODE_TO_HID`. Der Virtual-Key ist unabhängig davon, ob Shift oder
AltGr mitgehalten wird.
3. **Näherung ohne WinAPI** (keysym-Zeichentabelle, dann VK-Tabelle) — nur
relevant, wenn `versapad_keylayout` nicht verfügbar ist (Nicht-Windows,
kein ctypes). Auf dieser Ebene bleibt es bei der US-Layout-Näherung
inklusive vertauschtem Y/Z.
### Tastenbeschriftungen
`versapad_data.hid_key_name()` fragt für Zeichentasten `GetKeyNameTextW`
und zeigt damit den Namen des aktiven Layouts (deutsch: HID 0x1C → „Z“,
0x34 → „ä“). Für alles andere bleiben die gepflegten deutschen Namen aus
`_SPECIAL_KEYS` („Enter“, „Bild↑“, „Num5“) — die lesen sich besser als das,
was Windows dafür liefert („EINGABE“, „4 (ZEHNERTASTATUR)“).
Diese Namen sind zugleich Schlüssel (Dropdown-Einträge,
`hid_key_code_for_name()` für den MCP-Server) und müssen eindeutig bleiben.
Echte Kollisionen kommen vor: auf deutschem Layout heißt HID 0x31 schlicht
„#“, und diesen Namen trug bisher HID 0x32. Der Layoutname gewinnt, der
verdrängte US-Name wird als „# (US-Layout)“ gekennzeichnet statt verworfen.
`hid_key_code_for_name()` akzeptiert beide Schreibweisen; bei Kollision
gewinnt das Layout, damit `set_button_key(key="Z")` die Taste trifft, die
auf dieser Tastatur ein Z tippt.
Bestehende Belegungen ändern dadurch ihre **Anzeige, nicht ihre Daten**:
eine früher über das Dropdown gesetzte „Z“ steht als 0x1D in der Config und
wird jetzt wahrheitsgemäß als „Y“ angezeigt, weil sie auf dieser Tastatur
ein Y tippt. Ein Layoutwechsel zur Laufzeit wird nicht nachgezogen.
### Kopieren/Einfügen zwischen Tasten