src/switcher/state/ShortcutModifierResolverSpecs.md
ShortcutModifierResolver is the pure decision kernel for ATShortcut.modifiersMatch: given a
keyboard event's modifier set and a configured shortcut's modifiers, does the event match the
shortcut? Extracted from ATShortcut so its branch order is unit-tested (same rationale as
NativeHotkeyResolver, #5653). ATShortcut is the thin adapter that gathers the inputs from
SwitcherSession (is a session active, which hold modifiers apply), ControlsTab, and TilesView
(is the search field being edited), then calls this kernel.
All modifier arguments are cleaned Carbon bitmasks (CarbonModifierFlags.cleaned()). The kernel
only compares bits, so tests use opaque bit values.
event == event | shortcut).
This is the "is the activation modifier held" check, so extra modifiers don't disqualify it.event == shortcut & ~hold), so a configured ⌥⇥ keeps cycling on bare ⇥ once the switcher
is already showing. Only consulted when sessionActive; falls through otherwise.previousWindow = ⇧) is uppercasing input, not a command,
so it must not fire on its own; it is routed through SearchModeResolver.editingShortcutMatch
(isPrintable: true), which requires the hold modifiers (⌥⇧). This closes the #5781 gap: modifier-only
shortcuts arrive as flagsChanged (no keyDown), so they bypass TilesView.handleSearchEditingKeyDown
and would otherwise fire on the bare modifier, making capitals untypeable in search. The gate is
editing-only and modifier-only: key shortcuts (close = W, etc.) keep default matching here
because they're already gated upstream in routeKey.event == shortcut || event == shortcut | hold).Mirrors ShortcutModifierResolverTests.swift 1:1.
routeKey, not here).