src/switcher/state/SelectionResolverSpecs.md
Line coverage:
SelectionResolver.swift93% · refreshed 2026-05-27 by/coverage-explore
SelectionResolver decides which tile is highlighted while the switcher is open. Every time the
window list changes (a window opens/closes, an app steals focus, a search query filters the list), the
switcher calls SelectionResolver.decide(_:) with a snapshot of the current state and gets back a
SelectionDecision enum; the wrapper (Windows) turns that into highlight redraws, scroll-to-visible,
target bookkeeping, and the preview. Pure data in, Equatable decision out — no globals, no AppKit.
Once the user moves the highlight, the selected window's id is remembered as the target. On every refresh the resolver tries to keep the highlight on that same window even as the list reorders — this is the #5665 fix (before it, a background app finishing launch could yank the highlight away mid-pick).
restoreDefaultOnSearchClear) takes precedence — re-runs the initial pick even with no visible windows.clearTargetAndHover.bestMatchOnSearchChange) → jump to the first visible (best-scored) window.selectedTarget == nil, first refresh) → "from scratch" initial pick.selectAt).Initial-pick rules: with the last-focused rule, pick the visible non-windowless window with the lowest
lastFocusOrder; the both-top-minimized edge lands on index 0; otherwise cycle from 0 to the next
visible. Windowless app entries and invisible windows are skipped when scanning. findTarget only
matches a target id that is currently visible.
Mirrors SelectionResolverTests.swift 1:1. Groups: A initial pick · B preserve target (#5665) ·
C target removed · D search mode · E edge cases · plus direct helper-kernel checks.
selectedTarget == nil)clearTargetAndHover.resetThenSelect(0).lastFocusOrder.clearTargetAndHover.selectAt unchanged.selectedIndex → closest visible below.clearTargetAndHover.