aboutsummaryrefslogtreecommitdiff
path: root/src/workspace.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-03-31 13:29:57 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-03-31 13:29:57 +0300
commitf8c452294d6f76ccb264c0d9e205398492f00e18 (patch)
tree68f9505424de441b5da4dbe26fab6149e2a75734 /src/workspace.rs
parentb8ccdf600c750411b439d0eb41f6a70e3c595f4f (diff)
fix: terminate pane sessions on close
Diffstat (limited to 'src/workspace.rs')
-rw-r--r--src/workspace.rs32
1 files changed, 28 insertions, 4 deletions
diff --git a/src/workspace.rs b/src/workspace.rs
index 63e98912..39ee19a0 100644
--- a/src/workspace.rs
+++ b/src/workspace.rs
@@ -35,6 +35,15 @@ pub struct Workspace {
pub(crate) render_dirty: Arc<AtomicBool>,
}
+impl Drop for Workspace {
+ fn drop(&mut self) {
+ let runtimes = std::mem::take(&mut self.runtimes);
+ for (pane_id, runtime) in runtimes {
+ runtime.shutdown(pane_id);
+ }
+ }
+}
+
impl Workspace {
pub fn new(
initial_cwd: PathBuf,
@@ -111,12 +120,27 @@ impl Workspace {
/// Close the focused pane. Returns the removed pane id, or None if last pane.
pub fn close_focused(&mut self) -> Option<PaneId> {
let pane_id = self.layout.focused();
- self.remove_pane(pane_id)
+ self.close_pane(pane_id)
+ }
+
+ /// Close a specific pane and terminate everything running inside it.
+ /// Returns None if it's the last pane and the whole workspace should close.
+ pub fn close_pane(&mut self, pane_id: PaneId) -> Option<PaneId> {
+ let (removed, runtime) = self.detach_pane(pane_id)?;
+ if let Some(runtime) = runtime {
+ runtime.shutdown(pane_id);
+ }
+ Some(removed)
}
- /// Remove a specific pane from this workspace.
+ /// Remove a specific pane from this workspace without terminating its runtime.
+ /// Used when the pane process has already exited and we are only cleaning up state.
/// Returns None if it's the last pane and the whole workspace should close.
pub fn remove_pane(&mut self, pane_id: PaneId) -> Option<PaneId> {
+ self.detach_pane(pane_id).map(|(removed, _)| removed)
+ }
+
+ fn detach_pane(&mut self, pane_id: PaneId) -> Option<(PaneId, Option<PaneRuntime>)> {
if self.layout.pane_count() <= 1 {
return None;
}
@@ -141,12 +165,12 @@ impl Workspace {
self.next_public_pane_number = self.public_pane_numbers.len() + 1;
}
self.panes.remove(&pane_id);
- self.runtimes.remove(&pane_id);
+ let runtime = self.runtimes.remove(&pane_id);
self.zoomed = false;
if let Some(next_root) = next_root {
self.root_pane = next_root;
}
- Some(pane_id)
+ Some((pane_id, runtime))
}
fn promoted_root_if_needed(&self, closing: PaneId) -> Option<PaneId> {