You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Shortcuts: serialized saves, typing-safe bare-key dispatch, and macOS system-shortcut warnings
Three hardening fixes for the shortcuts subsystem:
- **Saves can't interleave.** Every store mutator fires `void saveToStore()`; two rapid mutations used to run their reconcile/delete/set/save loops concurrently over the shared store. Saves now chain (`saveChain`), so each starts after the previous finished and the last one always persists the final state. Covered by a rapid-mutations round-trip test.
- **Typing wins in text inputs.** A bare-key (or shift-only) Tier 1 binding — Tab → switch pane being the built-in case — used to fire mid-typing in any in-pane text input that forgot to `stopPropagation` (a per-component convention; only `NetworkLoginForm` did it). `handleGlobalKeyDown` now bails centrally when focus is in a text-editing element and the combo `isTypingKeyCombo` (new pure helper in `key-capture.ts`: no ⌘/⌃/⌥, not an F-key or Escape). ⌘-combos and F-keys stay live in inputs. Unit-tested red-first.
- **Capturing a macOS-owned combo warns honestly.** Binding ⌘Space (Spotlight), ⌃↑ (Mission Control), ⌘⇧4 (screenshots), and ~12 other system defaults used to save silently and then never fire — the OS intercepts first. The capture banner now shows a soft warning (`classifySystemShortcut` + `systemShortcutMessage`, checked only when there's no in-app conflict) with "Use anyway" (the user may have freed the combo in System Settings) and Cancel. macOS-display-form keys mean the list inherently can't misfire on other platforms.
- The banner's `ConflictKind` union growing a `command`-less variant forced honest narrowing: the template snapshots `conflictWarning.conflict` into an `{@const}` and branches exhaustively; the unit tests assert via `toMatchObject`.
|`license-section-utils.ts`| Pure label/status formatters extracted from `LicenseSection` for testability |
36
36
|`ram-gauge-utils.ts`| Pure stacked-bar segment math for `AiLocalSection`'s memory gauge (used → projected → free, plus warning thresholds) |
37
37
|`keyboard-shortcuts-grouping.ts`| Pure scope→group logic for `KeyboardShortcutsSection` (one titled group per `CommandScope`, fixed order). Tested by the set-equality regression guard |
38
-
|`keyboard-shortcuts-banner.ts`| Pure conflict-banner classification for `KeyboardShortcutsSection` (`classifyConflict` → native vs fixed vs normal; `reservedByMacOsMessage` / `fixedKeyMessage`). Native > fixed > normal in mixed sets. Unit-tested |
38
+
|`keyboard-shortcuts-banner.ts`| Pure conflict-banner classification for `KeyboardShortcutsSection` (`classifyConflict` → native vs fixed vs normal, `classifySystemShortcut` → soft macOS-system warning with "Use anyway"; `reservedByMacOsMessage` / `fixedKeyMessage` / `systemShortcutMessage`). Native > fixed > normal in mixed sets; system checked only when no in-app conflict. Unit-tested|
39
39
40
40
Each section ships with an `*.a11y.test.ts` (axe-core tier-3). `McpServerSection`, `UpdatesSection`, `SearchSection`,
41
41
`FileSystemWatchingSection`, and `KeyboardShortcutsSection` also have functional `*.test.ts` / `*.svelte.test.ts` files;
0 commit comments