diff options
Diffstat (limited to 'src/client/shell/overlay_input.rs')
| -rw-r--r-- | src/client/shell/overlay_input.rs | 91 |
1 files changed, 76 insertions, 15 deletions
diff --git a/src/client/shell/overlay_input.rs b/src/client/shell/overlay_input.rs index e4248304..10bd4a45 100644 --- a/src/client/shell/overlay_input.rs +++ b/src/client/shell/overlay_input.rs @@ -877,19 +877,7 @@ impl ClientShellState { if matches!(self.overlay, Some(ClientShellOverlay::ConfirmClose(_))) { if key.code == KeyCode::Enter { - let Some(ClientShellOverlay::ConfirmClose(confirm)) = self.overlay.take() else { - return; - }; - self.push_endpoint_method( - crate::api::schema::Method::WorkspaceClose( - crate::api::schema::WorkspaceCloseParams { - workspace_id: confirm.workspace_id, - close_group: true, - }, - ), - outcome, - ); - outcome.repaint = true; + self.accept_close_confirmation(outcome); } else if key.code == KeyCode::Esc { self.overlay = None; self.mode = ClientShellMode::Navigate; @@ -999,16 +987,74 @@ impl ClientShellState { outcome.repaint = true; } + pub(super) fn request_tab_close(&mut self, tab_id: String, outcome: &mut ClientShellInput) { + let workspace_id = self.snapshot.as_deref().and_then(|snapshot| { + let target = snapshot.tabs.iter().find(|tab| tab.tab_id == tab_id)?; + (self.config.confirm_close + && !snapshot + .tabs + .iter() + .any(|tab| tab.workspace_id == target.workspace_id && tab.tab_id != tab_id)) + .then(|| target.workspace_id.clone()) + }); + if let Some(workspace_id) = workspace_id { + if self.open_close_confirmation(workspace_id, Some(tab_id.clone())) { + outcome.repaint = true; + return; + } + } + self.push_endpoint_method( + crate::api::schema::Method::TabClose(crate::api::schema::TabTarget { tab_id }), + outcome, + ); + } + + pub(super) fn accept_close_confirmation(&mut self, outcome: &mut ClientShellInput) { + let Some(ClientShellOverlay::ConfirmClose(confirm)) = self.overlay.take() else { + return; + }; + outcome.repaint = true; + let method = if let Some(target) = confirm.tab_target { + if target.workspace.endpoint_id != self.active_endpoint_id + || !self.navigation_target_valid(&target.workspace) + || !self.snapshot.as_deref().is_some_and(|snapshot| { + snapshot.tabs.iter().any(|tab| { + tab.tab_id == target.tab_id + && tab.workspace_id == target.workspace.workspace_id + }) + }) + { + self.receive_endpoint_unavailable( + "Close target changed; try closing the tab again".into(), + ); + return; + } + crate::api::schema::Method::TabClose(crate::api::schema::TabTarget { + tab_id: target.tab_id, + }) + } else { + crate::api::schema::Method::WorkspaceClose(crate::api::schema::WorkspaceCloseParams { + workspace_id: confirm.workspace_id, + close_group: true, + }) + }; + self.push_endpoint_method(method, outcome); + } + pub(super) fn open_confirm_close_overlay(&mut self, workspace_id: String) { + self.open_close_confirmation(workspace_id, None); + } + + fn open_close_confirmation(&mut self, workspace_id: String, tab_id: Option<String>) -> bool { let Some(snapshot) = self.snapshot.as_deref() else { - return; + return false; }; let Some(workspace) = snapshot .workspaces .iter() .find(|workspace| workspace.workspace_id == workspace_id) else { - return; + return false; }; let group_key = workspace .worktree @@ -1030,6 +1076,19 @@ impl ClientShellState { }) .unwrap_or_else(|| vec![workspace]); let closes_group = group.len() > 1; + // Keep parent-group tab closes on the existing server confirmation path. + if tab_id.is_some() && closes_group { + return false; + } + let tab_target = if let Some(tab_id) = tab_id { + let Some(workspace) = self.navigation_target(&self.active_endpoint_id, &workspace_id) + else { + return false; + }; + Some(ClientTabCloseConfirmation { tab_id, workspace }) + } else { + None + }; let pane_count = group .iter() .map(|member| { @@ -1053,6 +1112,7 @@ impl ClientShellState { self.overlay = Some(ClientShellOverlay::ConfirmClose( ClientConfirmCloseOverlay { workspace_id, + tab_target, title: if closes_group { "Close worktree group?".to_owned() } else { @@ -1061,5 +1121,6 @@ impl ClientShellState { detail: format!("{} — {scope}", workspace.label), }, )); + true } } |
