diff options
| author | Eric Yue <jiacheng.yue@foxmail.com> | 2026-09-20 22:33:50 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-20 16:33:50 +0200 |
| commit | 74505861e40c48e070e711bd4de662a17b0939b3 (patch) | |
| tree | 736ad65c9dba956554529b4169bc54827dc342e3 /src/client/shell/workspace_navigation.rs | |
| parent | c00a62dda169beb472fc2f386d0f673ca100dfa4 (diff) | |
fix: keep workspace navigation visible in terminal theme (#4408)
* fix: keep workspace navigation visible in terminal theme
refs #4300
* fix: clear workspace highlight on directional pane focus
refs #4300
---------
Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
Diffstat (limited to 'src/client/shell/workspace_navigation.rs')
| -rw-r--r-- | src/client/shell/workspace_navigation.rs | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/src/client/shell/workspace_navigation.rs b/src/client/shell/workspace_navigation.rs index 6139fe0d..19fa1a39 100644 --- a/src/client/shell/workspace_navigation.rs +++ b/src/client/shell/workspace_navigation.rs @@ -9,6 +9,13 @@ pub(super) struct WorkspaceNavigationTarget { generation: Option<u64>, } +/// Display-only continuity while a direct focus request awaits its authoritative snapshot. +pub(super) struct PendingWorkspaceHighlight { + pub(super) target: WorkspaceNavigationTarget, + pub(super) request_id: String, + expires_at: std::time::Instant, +} + impl WorkspaceNavigationTarget { pub(super) fn matches(&self, endpoint_id: &ClientEndpointId, workspace_id: &str) -> bool { &self.endpoint_id == endpoint_id && self.workspace_id == workspace_id @@ -16,6 +23,35 @@ impl WorkspaceNavigationTarget { } impl ClientShellState { + pub(crate) fn tick_workspace_highlight(&mut self, now: std::time::Instant) -> bool { + if self + .pending_workspace_highlight + .as_ref() + .is_some_and(|pending| now >= pending.expires_at) + { + self.pending_workspace_highlight = None; + return true; + } + false + } + + pub(super) fn reconcile_pending_workspace_highlight(&mut self) { + if self + .pending_workspace_highlight + .as_ref() + .is_some_and(|pending| { + pending.target.endpoint_id != self.active_endpoint_id + || !self.navigation_target_valid(&pending.target) + || self.snapshot.as_deref().is_some_and(|snapshot| { + snapshot.focused_workspace_id.as_deref() + == Some(pending.target.workspace_id.as_str()) + }) + }) + { + self.pending_workspace_highlight = None; + } + } + pub(super) fn navigation_target( &self, endpoint_id: &ClientEndpointId, @@ -140,11 +176,25 @@ impl ClientShellState { outcome.repaint = true; return; } + let action_index = outcome.actions.len(); if self.focus_or_activate( - target.endpoint_id, - ClientEndpointFocusTarget::Workspace(target.workspace_id), + target.endpoint_id.clone(), + ClientEndpointFocusTarget::Workspace(target.workspace_id.clone()), outcome, ) { + // Endpoint handoffs already retain their coherent source frame in the runtime. + // Only retain a highlight if a focus request was actually enqueued. + if let Some(ClientShellAction::Endpoint { request, .. }) = + outcome.actions.get(action_index) + { + self.pending_workspace_highlight = Some(PendingWorkspaceHighlight { + target, + request_id: request.id.clone(), + // A later focus can be coalesced with this one before a snapshot is sent. + expires_at: std::time::Instant::now() + std::time::Duration::from_secs(1), + }); + self.reconcile_pending_workspace_highlight(); + } self.mode = ClientShellMode::Terminal; self.navigate_workspace_id = None; } |
