TASK 20 step 2: hotkey config UI + modifier chord persistence + conflict detection

This commit is contained in:
2026-08-26 06:48:14 -07:00
parent 89ab83be2e
commit 3a1484b3c5
12 changed files with 770 additions and 42 deletions
+12 -9
View File
@@ -960,7 +960,7 @@ The tasks below are ordered by dependency and risk. Each task builds on the prev
2. ✅ **TASK 3.18** — Chat box source — renders chat ON the stream. Depends on TASK 9.4 (same message parsing).
3. ✅ **TASK 10** — Polar billing — license key entry + watermark toggle + Velopack auto-updates (steps 1-7 shipped; Velopack update URL pending).
4. ✅ **TASK 19/23** — Control Surface UX — director's control room: thumbnails above central monitor, transitions (Cut/Fade/Move), edit mode offline only, left panel two-state (layers/props ↔ chat), right panel eliminated. Verified shipped 2026-08-24.
5. **TASK 20** — Hotkeys — global keyboard shortcuts. Step 1 (F1-F9 defaults) shipped 2026-08-24; config UI + persistence remain.
5. **TASK 20** — Hotkeys — global keyboard shortcuts. Steps 1-2 shipped 2026-08-26: F1-F9 defaults + config UI with modifier chords, persistence, conflict detection, unbinding.
5b. ✅ **Broadcast metadata pull-out + launch geometry** — shipped 2026-08-24 (row 29 above). Live-screen "Text" tab → broadcast form, persistence + remote update; window default/minimums bumped (1920×1040 / 1366×768) with size+position restore.
6. **TASK 17** — Web source (WebView2) — enables alert ecosystem.
7. **TASK 18** — Local recording — independent, but pairs with stream.
@@ -989,21 +989,24 @@ The tasks below are ordered by dependency and risk. Each task builds on the prev
**Goal:** keyboard shortcuts for scene switching and common actions — the single biggest UX gap.
### Status: ◐ In progress — step 1 shipped 2026-08-24
### Status: ◐ In progress — step 2 shipped 2026-08-26
1. ✅ `GlobalHotkeyManager` service — `Services/GlobalHotkeys.cs`: registers OS-level hotkeys on the window HWND via `RegisterHotKey`/`WM_HOTKEY` (`IHotkeyRegistrar` seam for tests; `RegistrarOverride` mirrors `LayoutPathOverride`). Wired in `MainWindow.OnSourceInitialized`.
2. ☑ Scene switching hotkeys — F1-F5 stage/transition the five canonical scenes. Fixed defaults; configurability deferred to the config UI step.
3. ☑ Common action hotkeys — F6 start/end stream, F7 mute mic, F8 mute desktop audio, F9 TRAX play/pause. Dispatch lives in `MainViewModel.HandleHotkey` and honors command gating.
4. ☐ Hotkey configuration UI — Settings dialog or per-scene hotkey picker
2. ✅ Scene switching hotkeys — F1-F5 stage/transition the five canonical scenes.
3. ✅ Common action hotkeys — F6 start/end stream, F7 mute mic, F8 mute desktop audio, F9 TRAX play/pause. Dispatch lives in `MainViewModel.HandleHotkey` and honors command gating.
4. ✅ Hotkey configuration UI — `HotkeyConfigDialog` (XAML Window + `HotkeyConfigViewModel`). Click-to-capture, "Unbind" per row, Reset to Defaults. Conflict detection shows a warning; user must unbind the conflicting action first. Modifier chords supported from day 1 (Ctrl+F10, Alt+Shift+F12, etc.).
5. ✅ Global hotkeys — work even when app is not focused (that is what `RegisterHotKey` gives us)
6. ☐ Conflict detection — warn when two actions share the same hotkey (impossible with fixed defaults; arrives with configurability)
7. ☐ Schema migration for hotkey bindings (persist across restarts)
8. ☑ Test: `GlobalHotkeyTests.WmHotkey_StagesScene_And_TogglesMic_And_RevokesOnClose` — real window + fake registrar, a genuine `WM_HOTKEY` posted through the window's own `HwndSource` hook stages the mapped scene and flips mic mute; close revokes every registration.
6. ✅ Conflict detection — warns when a chord is already bound to another action; user must unbind first.
7. ✅ Persistence — `LoadHotkeyBindings()` / `SaveHotkeyBindings()` in `LayoutStore`, stored as `"modifiers+vk"` in Settings table. No schema migration needed.
8. ✅ Test: `GlobalHotkeyTests.WmHotkey_StagesScene_And_TogglesMic_And_RevokesOnClose` — real window + fake registrar, a genuine `WM_HOTKEY` posted through the window's own `HwndSource` hook stages the mapped scene and flips mic mute; close revokes every registration.
9. ✅ Test: `HotkeyConfigTests` — round-trip persistence, display string formatting, storage serialization.
### Design decisions
- **Global hotkeys are mandatory** — streamers are in-game and cannot alt-tab. F1-F5 must work from anywhere.
- **Simple config** — one row per action: [Action] [Current Key] [Change]. No complex macro system.
- **Modifier chords from day 1** — Ctrl+F10, Alt+F1, etc. for Stream Deck support and power users.
- **Conflict = warning, not swap** — user must unbind the conflicting action before reassigning. No surprise reassignments.
- **Unbinding** — every action can be set to "None" (no hotkey). Explicitly unbound actions are absent from the DB.
- **No Stream Deck yet** — bare keyboard first. Stream Deck support (physical devices) is v1.1+.
---