fix(stacked): stacked panes can't resize status-bar (#4051)

* fix(typo): fix a typo in error message

* fix(typo): fix typo in Tip #6

* fix(logging): silence filesystem error

This `Option` chain already ends with `.unwrap_or_else(Default::default)`
so it's clearly expected that prior operations in the chain may fail. I
didn't have the default `layout_dir` on my computer, and it would fill my
logfile with unhelpful spam — on every pane creation, resize, etc.

* fix(stacked): stacked panes can't resize status-bar

* fix(e2e): race in multiple users test

---------

Co-authored-by: Aram Drevekenin <aram@poor.dev>
This commit is contained in:
Brooks Rady 2025-03-10 16:21:10 +00:00 committed by GitHub
parent 9f0056335d
commit 4fd0bac675
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 35 additions and 8 deletions

View file

@ -323,7 +323,7 @@ impl Page {
}
)),
ActiveComponent::new(TextOrCustomRender::Text(
Text::new("Press TAB to go to Chagne Mode Behavior")
Text::new("Press TAB to go to Change Mode Behavior")
.color_range(3, 6..=9)
)),
ActiveComponent::new(TextOrCustomRender::Text(

View file

@ -1799,7 +1799,9 @@ pub fn multiple_users_in_different_panes_and_same_tab() {
name: "take snapshot after",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.status_bar_appears()
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
&& remote_terminal.snapshot_contains("LOCK")
{
// cursor is in the newly opened second pane
step_is_complete = true;

View file

@ -54,7 +54,10 @@ impl<'a> PaneResizer<'a> {
let spans = self
.discretize_spans(grid, space)
.map_err(|err| anyhow!("{}", err))?;
self.apply_spans(spans)?;
if self.is_layout_valid(&spans) {
self.apply_spans(spans)?;
}
Ok(())
}
@ -128,6 +131,31 @@ impl<'a> PaneResizer<'a> {
Ok(grid.into_iter().flatten().collect())
}
// HACK: This whole function is a bit of a hack — it's here to stop us from breaking the layout if we've been given
// a bad state to start with. If this function returns false, nothing is resized.
fn is_layout_valid(&self, spans: &[Span]) -> bool {
// If pane stacks are too tall to fit on the screen, abandon ship before the status bar gets caught up in
// any erroneous resizing...
for span in spans {
let pane_is_stacked = self
.panes
.borrow()
.get(&span.pid)
.unwrap()
.current_geom()
.is_stacked();
if pane_is_stacked && span.direction == SplitDirection::Vertical {
let min_stack_height = StackedPanes::new(self.panes.clone())
.min_stack_height(&span.pid)
.unwrap();
if span.size.as_usize() < min_stack_height {
return false;
}
}
}
true
}
fn apply_spans(&mut self, spans: Vec<Span>) -> Result<()> {
let err_context = || format!("Failed to apply spans");
let mut geoms_changed = false;

View file

@ -309,7 +309,7 @@ impl<'a> StackedPanes<'a> {
Ok(())
}
fn pane_is_one_liner(&self, id: &PaneId) -> Result<bool> {
let err_context = || format!("Cannot determin if pane is one liner or not");
let err_context = || format!("Cannot determine if pane is one liner or not");
let panes = self.panes.borrow();
let pane_to_close = panes.get(id).with_context(err_context)?;
Ok(pane_to_close.position_and_size().rows.is_fixed())

View file

@ -1157,10 +1157,7 @@ impl Layout {
.or_else(|| default_layout_dir())
.and_then(|layout_dir| match std::fs::read_dir(layout_dir) {
Ok(layout_files) => Some(layout_files),
Err(e) => {
log::error!("Failed to read layout dir: {:?}", e);
None
},
Err(_) => None,
})
.map(|layout_files| {
let mut available_layouts = vec![];