diff --git a/docs/changelog.md b/docs/changelog.md index 4c6a4c986..f29da64b4 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -59,6 +59,7 @@ As features stabilize some brief notes about them will accumulate here. * Fixed: fonts with emoji presentation are shifted to better align with the primary font baseline [#1203](https://github.com/wez/wezterm/issues/1203) * New: [window_padding](config/lua/config/window_padding.md) now accepts values such as `"1cell"` or `"30%"` to compute values based on font or window metrics. * New: BSDish systems now support [toast notifications](https://github.com/wez/wezterm/issues/489) +* Fixed: the whole tab was closed when only the zoomed pane exited. [#1235](https://github.com/wez/wezterm/issues/1235) ### 20210814-124438-54e29167 diff --git a/mux/src/tab.rs b/mux/src/tab.rs index f9ffe3ef1..a24c862fb 100644 --- a/mux/src/tab.rs +++ b/mux/src/tab.rs @@ -560,23 +560,35 @@ impl Tab { /// Walks the pane tree to produce the topologically ordered flattened /// list of PositionedPane instances along with their positioning information. pub fn iter_panes(&self) -> Vec { + self.iter_panes_impl(true) + } + + /// Like iter_panes, except that it will include all panes, regardless of + /// whether one of them is currently zoomed. + pub fn iter_panes_ignoring_zoom(&self) -> Vec { + self.iter_panes_impl(false) + } + + fn iter_panes_impl(&self, respect_zoom_state: bool) -> Vec { let mut panes = vec![]; - if let Some(zoomed) = self.zoomed.borrow().as_ref() { - let size = *self.size.borrow(); - panes.push(PositionedPane { - index: 0, - is_active: true, - is_zoomed: true, - left: 0, - top: 0, - width: size.cols.into(), - pixel_width: size.pixel_width.into(), - height: size.rows.into(), - pixel_height: size.pixel_height.into(), - pane: Rc::clone(zoomed), - }); - return panes; + if respect_zoom_state { + if let Some(zoomed) = self.zoomed.borrow().as_ref() { + let size = *self.size.borrow(); + panes.push(PositionedPane { + index: 0, + is_active: true, + is_zoomed: true, + left: 0, + top: 0, + width: size.cols.into(), + pixel_width: size.pixel_width.into(), + height: size.rows.into(), + pixel_height: size.pixel_height.into(), + pane: Rc::clone(zoomed), + }); + return panes; + } } let active_idx = *self.active.borrow(); @@ -1119,6 +1131,7 @@ impl Tab { F: Fn(usize, &Rc) -> bool, { let mut dead_panes = vec![]; + let zoomed_pane = self.zoomed.borrow().as_ref().map(|p| p.pane_id()); { let root_size = *self.size.borrow(); @@ -1147,6 +1160,10 @@ impl Tab { if pane_index == active_idx { active_idx = pane_index.saturating_sub(1); } + if Some(pane.pane_id()) == zoomed_pane { + // If we removed the zoomed pane, un-zoom our state! + self.zoomed.borrow_mut().take(); + } let parent; match cursor.unsplit_leaf() { Ok((c, dead, p)) => { @@ -1225,7 +1242,9 @@ impl Tab { } pub fn is_dead(&self) -> bool { - let panes = self.iter_panes(); + // Make sure we account for all panes, so that we don't + // kill the whole tab if the zoomed pane is dead! + let panes = self.iter_panes_ignoring_zoom(); let mut dead_count = 0; for pos in &panes { if pos.pane.is_dead() {