Stop WorkspacesModel reads from building generic key paths
Fixes #15439. The macOS app no longer rebuilds workspace pane overlays on unrelated SwiftUI updates, and workspace model reads no longer instantiate generic Observation key paths on every access.
What changed
WorkspacesModel<Tab>keeps its generic public API but recordstabs,workspaceGroups, andselectedTabIdthrough a cached, non-generic main-actor registrar.WorkspacesModelowns the workspace ID index;TabManager.selectedWorkspacenow performs an O(1) lookup.- The overlay experiment target is cached and updated from defaults changes.
- A per-window overlay coordinator admits immutable input snapshots through
WindowAccessor(refreshID:); selection, unread state, flash tokens, settings, focus/layout notifications, geometry, and window changes share one refresh gate. - New app files are wired into
cmux.xcodeproj. - The SSH startup script array assembly is split into sequential appends to avoid an unrelated Swift compiler type-check timeout in macOS compile admission; generated script contents are unchanged.
Evidence
Sentry groups addressed: CMUXTERM-MACOS-3VND, 26HC, 1FZE, 1RP3, 1QJ5, 25BX, 3RPW, 3EM0, 3VFT, 3QY3, 3VMA, 2FTA, 2F5G, 1MDH, and 3BRW. The related defaults lookup group is 1SKP.
The package benchmark ran on the macOS CI builder. Before the registrar fix, selectedTabId measured 1,313.6 ns/read versus a 186.1 ns/read non-generic control (7.1x); after the fix it measured 186.0 versus 185.2 ns/read (1.0x). The benchmark reports measurements without a wall-clock pass/fail threshold so scheduler variance cannot make shared CI flaky.
No Sources/TabManager.swift or Packages/macOS/CmuxWorkspaces change landed between v0.64.24 (f5da007dd8) and v0.64.25 (b685a275c2). The Sentry groups predate that release, so the evidence supports increased read frequency and runtime metadata contention as the release symptom rather than a source regression in those files.
Design trade-off
The model remains generic for source compatibility. Its observation registrar is a separate non-generic main-actor owner, which preserves per-property invalidation and the legacy Combine bridges while avoiding generic key-path metadata work. The overlay has one per-window coordinator: the SwiftUI leaf reads the input snapshot, and geometry/glass-root events feed the same gate because they originate outside SwiftUI. Unread and flash state remain observable model values rather than notification side channels.
Testing
python3 scripts/verify-local.py --only swift-syntax --swift-changedpython3 scripts/verify-local.py --only test-wiringpython3 scripts/swift_file_length_budget.py- macOS CI
swift-package-tests:WorkspacesModelObservationTests,WorkspacesModelReadCostTests, and the existingWorkspacesModelTests - macOS CI compile admission and routed app-host tests
- Regression coverage for observation ordering, per-member invalidation, O(1) indexing, overlay window refresh deduplication, and flash/settings/unread invalidation
Follow-up
Sentry verification is post-release: confirm no new events for the listed groups on the fixed build.
Checklist
- Focused regression and benchmark added before the fix commit.
- Current-head package and macOS compile checks run in CI.
- New app source files wired into the app target.
- Dogfood tagged build: pending Austin authorization; no app was launched or replaced on this Mac.
- Sentry post-release verification: pending release.
Changelog
Fixed: Workspace observation and tmux overlay refreshes no longer perform repeated generic key-path/defaults work on unrelated UI updates.
Summary by CodeRabbit
- New Features
- Added restored unread indicators for workspace panels.
- Improved workspace pane overlays, including pane borders, unread indicators, and flash effects.
- Bug Fixes
- Workspace overlays now refresh more reliably when window, layout, geometry, or backdrop changes occur.
- Improved the reliability of workspace unread indicators and pane flashes, including when notifications or flashes repeat.