diff --git a/frontends/rioterm/src/layout/compute_tests.rs b/frontends/rioterm/src/layout/compute_tests.rs index fae0f90fc2..40ef8e4010 100644 --- a/frontends/rioterm/src/layout/compute_tests.rs +++ b/frontends/rioterm/src/layout/compute_tests.rs @@ -647,3 +647,73 @@ fn test_split_inside_resized_panel_preserves_proportions() { "Bottom (bottom half) should be ~400px tall, got {bottom_h}" ); } + +// --- update_scaled_margin ------------------------------------------------ + +fn margin_test_dimension() -> ContextDimension { + let dims = TextDimensions { + width: 8.0, + height: 16.0, + scale: 1.0, + }; + ContextDimension::build( + 800.0, + 600.0, + dims, + cell_for(dims), + 1.0, + 14.0, + Margin::all(0.0), + ) +} + +/// Build a single-panel grid off sugarloaf (positions come from +/// `calculate_positions`, not `apply_taffy_layout`). +fn single_panel_grid() -> ContextGrid { + use crate::context::create_mock_context; + use rio_backend::event::VoidListener; + use rio_window::window::WindowId; + + let first = create_mock_context( + VoidListener {}, + WindowId::from(0), + 0, + margin_test_dimension(), + ); + ContextGrid::new( + first, + Margin::all(0.0), + [0.0; 4], + [0.0; 4], + rio_backend::config::layout::Panel::default(), + ) +} + +/// Regression: when the top window margin grows (e.g. the tab bar +/// becomes visible after a second tab is created), `update_scaled_margin` +/// must refresh Taffy's root size. Otherwise the next layout pass uses +/// the stale available area and the panel keeps its old height — leaving +/// the bottom rows clipped behind the tab bar. +#[test] +fn test_update_scaled_margin_shrinks_panel_when_top_margin_grows() { + let mut grid = single_panel_grid(); + let panel = grid.current; + + let initial_height = grid.inner[&panel].layout_rect[3]; + assert!( + initial_height > 0.0, + "panel should have a positive initial height" + ); + + let tab_bar_height = 34.0; + grid.update_scaled_margin(Margin::new(tab_bar_height, 0.0, 0.0, 0.0)); + grid.calculate_positions(); + + let new_height = grid.inner[&panel].layout_rect[3]; + assert!( + (initial_height - new_height - tab_bar_height).abs() < 1.0, + "panel height should shrink by the new top margin: was {initial_height}, \ + now {new_height}, expected ~{}", + initial_height - tab_bar_height + ); +} diff --git a/frontends/rioterm/src/layout/mod.rs b/frontends/rioterm/src/layout/mod.rs index 4edd878eee..0aa28220b4 100644 --- a/frontends/rioterm/src/layout/mod.rs +++ b/frontends/rioterm/src/layout/mod.rs @@ -1169,6 +1169,12 @@ impl ContextGrid { pub fn update_scaled_margin(&mut self, scaled_margin: Margin) { self.scaled_margin = scaled_margin; + // The Taffy root size is `window - scaled_margin`. Changing the + // margin without refreshing it leaves the next `compute_layout` + // running against a stale available area, so panels keep their + // old size (e.g. the tab bar appearing eats into the terminal + // height but the PTY never shrinks). + let _ = self.try_update_size(self.width, self.height); } pub fn update_line_height(&mut self, line_height: f32) {