aboutsummaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-08-09 04:17:28 +0300
committerGitHub <noreply@github.com>2026-08-09 04:17:28 +0300
commit97f8140f37976e1552f4eee151590412f33075cc (patch)
tree4b42f7e95cf61f84a04268e5f22623b21d467008 /src/ui
parent1777e9bba32b953ed1ad203b4a16d01105539000 (diff)
fix(ui): reclaim scrollbar gutter in alternate screen (#2538)
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/panes.rs58
1 files changed, 53 insertions, 5 deletions
diff --git a/src/ui/panes.rs b/src/ui/panes.rs
index 22daddf8..df9813cf 100644
--- a/src/ui/panes.rs
+++ b/src/ui/panes.rs
@@ -31,8 +31,11 @@ fn pane_border_title(label: &str, pane_width: u16, _focused: bool) -> Option<Str
Some(format!(" {} ", truncate_end(label, max_label_width)))
}
-fn stable_terminal_inner_rect(pane_inner: Rect, pane_scrollbars: bool) -> Rect {
- if !pane_scrollbars || pane_inner.width <= 4 {
+fn terminal_inner_rect(rt: &TerminalRuntime, pane_inner: Rect, pane_scrollbars: bool) -> Rect {
+ if !pane_scrollbars
+ || pane_inner.width <= 4
+ || rt.input_state().is_some_and(|state| state.alternate_screen)
+ {
return pane_inner;
}
@@ -175,7 +178,7 @@ fn stable_scrollbar_gutter(
pane_inner: Rect,
pane_scrollbars: bool,
) -> (Rect, Option<Rect>) {
- let inner_rect = stable_terminal_inner_rect(pane_inner, pane_scrollbars);
+ let inner_rect = terminal_inner_rect(rt, pane_inner, pane_scrollbars);
if inner_rect == pane_inner {
return (inner_rect, None);
}
@@ -212,7 +215,7 @@ pub(super) fn resize_tab_panes(
Borders::NONE
};
let pane_inner = pane_inner_rect(area, borders);
- let inner_rect = stable_terminal_inner_rect(pane_inner, app.pane_scrollbars);
+ let inner_rect = terminal_inner_rect(rt, pane_inner, app.pane_scrollbars);
if !app.direct_attach_resize_locks.contains(terminal_id) {
rt.resize(
inner_rect.height,
@@ -234,7 +237,7 @@ pub(super) fn resize_tab_panes(
let pane_inner = pane_inner_rect(info.rect, info.borders);
if let Some((terminal_id, rt)) = runtime_for_tab_pane(terminal_runtimes, tab, info.id) {
- let inner_rect = stable_terminal_inner_rect(pane_inner, app.pane_scrollbars);
+ let inner_rect = terminal_inner_rect(rt, pane_inner, app.pane_scrollbars);
if !app.direct_attach_resize_locks.contains(terminal_id) {
rt.resize(
inner_rect.height,
@@ -1339,6 +1342,51 @@ mod tests {
}
#[tokio::test]
+ async fn alternate_screen_reclaims_scrollbar_gutter_and_restores_it_on_exit() {
+ let mut app = AppState::test_new();
+ let mut workspace = Workspace::test_new("test");
+ let root_pane = workspace.tabs[0].root_pane;
+ workspace.tabs[0].runtimes.insert(
+ root_pane,
+ TerminalRuntime::test_with_scrollback_bytes(
+ 40,
+ 8,
+ 1024,
+ b"one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten\n",
+ ),
+ );
+ app.workspaces = vec![workspace];
+ app.active = Some(0);
+
+ let area = Rect::new(10, 3, 40, 8);
+ let terminal_runtimes = TerminalRuntimeRegistry::new();
+ let assert_geometry = |expected_width, has_scrollbar| {
+ let infos = compute_pane_infos(
+ &app,
+ &terminal_runtimes,
+ area,
+ true,
+ crate::kitty_graphics::HostCellSize::default(),
+ );
+ assert_eq!(
+ infos[0].inner_rect,
+ Rect::new(area.x, area.y, expected_width, area.height)
+ );
+ assert_eq!(infos[0].scrollbar_rect.is_some(), has_scrollbar);
+ assert_eq!(
+ app.workspaces[0].tabs[0].runtimes[&root_pane].current_size(),
+ (area.height, expected_width)
+ );
+ };
+
+ assert_geometry(39, true);
+ app.workspaces[0].tabs[0].runtimes[&root_pane].test_process_pty_bytes(b"\x1b[?1049h");
+ assert_geometry(40, false);
+ app.workspaces[0].tabs[0].runtimes[&root_pane].test_process_pty_bytes(b"\x1b[?1049l");
+ assert_geometry(39, true);
+ }
+
+ #[tokio::test]
async fn zoomed_pane_scrollbar_gutter_is_reserved_before_scrollback_exists() {
let mut app = AppState::test_new();
let mut workspace = Workspace::test_new("test");