From bdfcfb0abdd1c064eced5d49f4ac72ddf6e83df6 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Sat, 22 Feb 2025 12:45:30 +0100 Subject: [PATCH] fix(stacked-panes): better handling of adding new panes to a stack (#4016) * fix(stacked-panes): better handling of adding new panes to a stack * style(fmt): rustfmt * docs(changelog): document --- CHANGELOG.md | 2 +- zellij-server/src/panes/tiled_panes/mod.rs | 8 ++++++-- zellij-server/src/panes/tiled_panes/stacked_panes.rs | 9 ++++++--- .../src/panes/tiled_panes/tiled_pane_grid.rs | 2 +- zellij-server/src/tab/mod.rs | 11 ++++++++--- ...sts__screen_can_move_pane_to_a_new_tab_left-4.snap | 4 ++-- ...ts__screen_can_move_pane_to_a_new_tab_right-4.snap | 4 ++-- ..._tests__send_cli_toggle_pane_embed_or_float-3.snap | 4 ++-- zellij-utils/src/input/layout.rs | 4 ++++ 9 files changed, 32 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcdae5fc..829bbd10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * fix(terminal): support setting kitty keyboard protocol with `CSI=` (https://github.com/zellij-org/zellij/pull/3942) * fix(floating-panes): handle various errors (https://github.com/zellij-org/zellij/pull/3944) * chore(rust): Update Rust toolchain to 1.84.0 (https://github.com/zellij-org/zellij/pull/3945) -* feat(ux): stacked-resize (https://github.com/zellij-org/zellij/pull/3957, https://github.com/zellij-org/zellij/pull/4003 and https://github.com/zellij-org/zellij/pull/4011) +* feat(ux): stacked-resize (https://github.com/zellij-org/zellij/pull/3957, https://github.com/zellij-org/zellij/pull/4003, https://github.com/zellij-org/zellij/pull/4011 and https://github.com/zellij-org/zellij/pull/4016) * feat(plugins): API to change the position and size of floating pane, as well as know the viewport size (https://github.com/zellij-org/zellij/pull/3958 and https://github.com/zellij-org/zellij/pull/3972) * feat(plugins): add `PastedText` event (https://github.com/zellij-org/zellij/pull/3962) * feat(plugins): APIs to open panes near plugin (https://github.com/zellij-org/zellij/pull/3966) diff --git a/zellij-server/src/panes/tiled_panes/mod.rs b/zellij-server/src/panes/tiled_panes/mod.rs index 40048cfd..42bbe7f7 100644 --- a/zellij-server/src/panes/tiled_panes/mod.rs +++ b/zellij-server/src/panes/tiled_panes/mod.rs @@ -355,8 +355,12 @@ impl TiledPanes { self.panes.insert(pane_id, pane); // TODO: is set_geom the right one? return; }, - Err(e) => { - log::error!("Failed to add pane to stack: {:?}", e); + Err(_e) => { + return self.add_pane_without_stacked_resize( + pane_id, + pane, + should_relayout, + ); }, } }, diff --git a/zellij-server/src/panes/tiled_panes/stacked_panes.rs b/zellij-server/src/panes/tiled_panes/stacked_panes.rs index 748e4fc6..81d15ea3 100644 --- a/zellij-server/src/panes/tiled_panes/stacked_panes.rs +++ b/zellij-server/src/panes/tiled_panes/stacked_panes.rs @@ -1,4 +1,7 @@ -use crate::{panes::PaneId, tab::Pane}; +use crate::{ + panes::PaneId, + tab::{Pane, MIN_TERMINAL_HEIGHT}, +}; use std::cell::RefCell; use std::collections::{HashMap, HashSet}; use std::rc::Rc; @@ -419,7 +422,7 @@ impl<'a> StackedPanes<'a> { for stack in all_stacks { if let Some((id_of_flexible_pane_in_stack, _flexible_pane_in_stack)) = stack .iter() - .find(|(_p_id, p)| !p.rows.is_fixed() && p.rows.as_usize() > 1) + .find(|(_p_id, p)| !p.rows.is_fixed() && p.rows.as_usize() > MIN_TERMINAL_HEIGHT) { self.make_lowest_pane_in_stack_flexible(id_of_flexible_pane_in_stack)?; let all_stacked_pane_positions = @@ -452,7 +455,7 @@ impl<'a> StackedPanes<'a> { let stack = self.positions_in_stack(pane_id).with_context(err_context)?; if let Some((id_of_flexible_pane_in_stack, _flexible_pane_in_stack)) = stack .iter() - .find(|(_p_id, p)| !p.rows.is_fixed() && p.rows.as_usize() > 1) + .find(|(_p_id, p)| !p.rows.is_fixed() && p.rows.as_usize() > MIN_TERMINAL_HEIGHT) { self.make_lowest_pane_in_stack_flexible(id_of_flexible_pane_in_stack)?; let all_stacked_pane_positions = diff --git a/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs b/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs index 03581f16..5f2bf834 100644 --- a/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs +++ b/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs @@ -1411,7 +1411,7 @@ impl<'a> TiledPaneGrid<'a> { .collect(); flexible_pane_in_stack .iter() - .any(|(_p_id, p)| p.current_geom().rows.as_usize() > 1) + .any(|(_p_id, p)| p.current_geom().rows.as_usize() > MIN_TERMINAL_HEIGHT) } pub fn make_room_in_stack_for_pane(&mut self) -> Result { StackedPanes::new(self.panes.clone()).make_room_for_new_pane() diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index 71bb3bea..75032fff 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -825,7 +825,7 @@ impl Tab { .swap_layouts .swap_tiled_panes(&self.tiled_panes, search_backwards) { - LayoutApplier::new( + let application_res = LayoutApplier::new( &self.viewport, &self.senders, &self.sixel_image_store, @@ -846,8 +846,13 @@ impl Tab { self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, ) - .apply_tiled_panes_layout_to_existing_panes(&layout_candidate) - .non_fatal(); + .apply_tiled_panes_layout_to_existing_panes(&layout_candidate); + if application_res.is_err() { + self.swap_layouts.set_is_tiled_damaged(); + application_res.non_fatal(); + } + } else { + self.swap_layouts.set_is_tiled_damaged(); } self.tiled_panes.reapply_pane_frames(); let display_area = *self.display_area.borrow(); diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_move_pane_to_a_new_tab_left-4.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_move_pane_to_a_new_tab_left-4.snap index 112a5705..77c5a5a3 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_move_pane_to_a_new_tab_left-4.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_move_pane_to_a_new_tab_left-4.snap @@ -1,9 +1,9 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 3636 +assertion_line: 3649 expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ pane_to_break_free ──────────────────┐┌ pane_to_stay ────────────────────────┐ +00 (C): ┌ pane_to_stay ────────────────────────┐┌ pane_to_break_free ──────────────────┐ 01 (C): │ ││ │ 02 (C): │ ││ │ 03 (C): │ ││ │ diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_move_pane_to_a_new_tab_right-4.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_move_pane_to_a_new_tab_right-4.snap index 8a3cfe42..ef8a4d90 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_move_pane_to_a_new_tab_right-4.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_move_pane_to_a_new_tab_right-4.snap @@ -1,9 +1,9 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 3587 +assertion_line: 3601 expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ pane_to_break_free ──────────────────┐┌ pane_to_stay ────────────────────────┐ +00 (C): ┌ pane_to_stay ────────────────────────┐┌ pane_to_break_free ──────────────────┐ 01 (C): │ ││ │ 02 (C): │ ││ │ 03 (C): │ ││ │ diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_pane_embed_or_float-3.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_pane_embed_or_float-3.snap index f2bcd76f..5a16d92e 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_pane_embed_or_float-3.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_pane_embed_or_float-3.snap @@ -1,9 +1,9 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2569 +assertion_line: 2583 expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ Pane #1 ─────────────────────────────┐┌ Pane #2 ─────────────────────────────┐ +00 (C): ┌ Pane #2 ─────────────────────────────┐┌ Pane #1 ─────────────────────────────┐ 01 (C): │ ││ │ 02 (C): │ ││ │ 03 (C): │ ││ │ diff --git a/zellij-utils/src/input/layout.rs b/zellij-utils/src/input/layout.rs index f69975fc..8e3dbd53 100644 --- a/zellij-utils/src/input/layout.rs +++ b/zellij-utils/src/input/layout.rs @@ -1631,6 +1631,10 @@ fn split_space( } else if let Some(last_size) = sizes.last_mut() { *last_size = None; } + if sizes.len() > space_to_split.rows.as_usize().saturating_sub(4) { + // 4 is MIN_TERMINAL_HEIGHT + return Err("Not enough room for stacked panes in this layout"); + } sizes } else if ignore_percent_split_sizes { layout