Fix workspace notification ring invalidation blanking active terminal
Summary
- add a workspace-scoped notification presentation model and regression tests
- update workspace content to observe notification changes only for its own workspace
- update sidebar rows to observe their own workspace notification presentation so background workspaces do not invalidate sibling rows
Closes #2887
[!NOTE]
Medium Risk
Touches notification indexing and several UI update paths (workspace content, sidebar rows, command palette) via new snapshot/publisher logic; regressions could cause stale/missing badges or rings but the scope is localized and covered by new tests.
Overview
Fixes cross-workspace notification updates from invalidating unrelated UI by introducing a per-workspace notification snapshot model and publishers.
TerminalNotificationStore now builds and publishes TerminalNotificationWorkspaceSnapshot (unread/read presence, per-surface visibility including focused read indicator, latest notification), plus per-tab WorkspaceNotificationPresentationStore instances cached via WorkspaceNotificationPresentationStoreCache.
ContentView, WorkspaceContentView, and sidebar TabItemView are refactored to consume these workspace-scoped snapshots/stores (including tmux overlay/unread rect calculations and command palette context flags), with cache pruning on tab changes. Adds regression tests for snapshot correctness, per-workspace isolation, stale-snapshot fallback, and cache pruning, plus a small File Explorer test stabilization around pending expansion completion.
Reviewed by Cursor Bugbot for commit fc4843147d182ee4873172019dbf47d1fde1e81b. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Fixes a bug where notifications from other workspaces invalidated the active workspace and blanked its terminal. Scopes notification state per workspace so rings/overlays, sidebar badges, and the command palette stay accurate and reactive. Closes #2887.
- Bug Fixes
- Added a per-workspace
TerminalNotificationWorkspaceSnapshot(unread count, read presence, per-surface unread and visible sets incl. focused read indicator, latest notification). - Introduced per-tab
WorkspaceNotificationPresentationStorecached viaWorkspaceNotificationPresentationStoreCache; sidebar rows observe their own store for unread count and latest message to avoid cross-row invalidation and flicker. ContentViewcaches the selected workspace snapshot, updates it viaworkspaceSnapshotPublisher(forTabId:), prunes stale presentation stores on tab changes, usesvisibleSurfaceIdsfor unread rects, and drives command palette read/unread from snapshots.WorkspaceContentViewsubscribes toworkspaceSnapshotPublisher(forTabId:)and usesvisibleSurfaceIdsfor unread rings and tmux overlay rects.- Switched views to
TerminalNotificationStore.sharedto reduce environment-driven invalidations; added publishers (presentationPublisher/workspaceSnapshotPublisher) for reactive updates. - Tests cover presentation isolation, latest+focused indicator inclusion, stale-snapshot fallback, and cache pruning; stabilized File Explorer hydration by awaiting pending expansions.
- Added a per-workspace
Summary by CodeRabbit
-
Refactor
- Notification state moved to per-workspace snapshots with cached per-tab presentation stores to reduce per-row observation and improve responsiveness when switching tabs/workspaces.
-
New Features
- Sidebar and tab badges now derive unread/visible indicators from workspace snapshots for more accurate, consistent updates.
-
Bug Fixes
- Reduced unnecessary badge recomputation and UI churn; notification overlays more stable. Also ensured certain async file-explorer tasks run on the main actor to avoid timing issues.
-
Tests
- Added tests covering presentation/snapshot behavior and notification visibility across workspaces.