aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-04-25 23:08:01 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-04-25 23:08:01 +0300
commit692327f38b752e868988e789d27e9098e4b7e34e (patch)
tree401255da700f823104f917ab25b886c32ff360d2
parentd15fa7aae4e6da3d30ea000c4ea9d0934fbee2e5 (diff)
fix: reserve pane scrollbar column
-rw-r--r--src/ui.rs10
-rw-r--r--src/ui/panes.rs43
2 files changed, 44 insertions, 9 deletions
diff --git a/src/ui.rs b/src/ui.rs
index 5c791fec..4299019f 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -492,11 +492,11 @@ mod tests {
}
#[test]
- fn pane_scrollbar_rect_overlays_rightmost_inner_column() {
+ fn pane_scrollbar_rect_uses_reserved_rightmost_column() {
let info = PaneInfo {
id: crate::layout::PaneId::from_raw(1),
rect: Rect::new(0, 0, 12, 8),
- inner_rect: Rect::new(1, 1, 10, 6),
+ inner_rect: Rect::new(1, 1, 9, 6),
scrollbar_rect: Some(Rect::new(10, 1, 1, 6)),
is_focused: true,
};
@@ -505,7 +505,7 @@ mod tests {
}
#[tokio::test]
- async fn compute_view_keeps_terminal_width_when_pane_scrollbar_is_visible() {
+ async fn compute_view_reserves_terminal_column_when_pane_scrollbar_is_visible() {
let mut app = crate::app::state::AppState::test_new();
let mut ws = Workspace::test_new("test");
let pane_id = ws.tabs[0].root_pane;
@@ -526,11 +526,11 @@ mod tests {
compute_view(&mut app, Rect::new(0, 0, 40, 12));
let info = app.view.pane_infos.first().expect("pane info");
- assert_eq!(info.inner_rect.width, app.view.terminal_area.width);
+ assert_eq!(info.inner_rect.width + 1, app.view.terminal_area.width);
assert_eq!(
info.scrollbar_rect,
Some(Rect::new(
- info.inner_rect.x + info.inner_rect.width.saturating_sub(1),
+ info.inner_rect.x + info.inner_rect.width,
info.inner_rect.y,
1,
info.inner_rect.height,
diff --git a/src/ui/panes.rs b/src/ui/panes.rs
index 7e1490db..7a4a2c74 100644
--- a/src/ui/panes.rs
+++ b/src/ui/panes.rs
@@ -26,13 +26,14 @@ pub(super) fn compute_pane_infos(app: &AppState, area: Rect, resize_panes: bool)
if ws.zoomed {
let focused_id = ws.layout.focused();
- let inner_rect = area;
+ let mut inner_rect = area;
let mut scrollbar_rect = None;
if let Some(rt) = ws.runtimes.get(&focused_id) {
if rt
.scroll_metrics()
- .is_some_and(|metrics| should_show_scrollbar(metrics) && area.width > 0)
+ .is_some_and(|metrics| should_show_scrollbar(metrics) && area.width > 1)
{
+ inner_rect.width = inner_rect.width.saturating_sub(1);
scrollbar_rect = Some(Rect::new(
area.x + area.width.saturating_sub(1),
area.y,
@@ -70,13 +71,14 @@ pub(super) fn compute_pane_infos(app: &AppState, area: Rect, resize_panes: bool)
area
};
- let inner_rect = pane_inner;
+ let mut inner_rect = pane_inner;
let mut scrollbar_rect = None;
if let Some(rt) = ws.runtimes.get(&info.id) {
if rt
.scroll_metrics()
- .is_some_and(|metrics| should_show_scrollbar(metrics) && pane_inner.width > 0)
+ .is_some_and(|metrics| should_show_scrollbar(metrics) && pane_inner.width > 1)
{
+ inner_rect.width = inner_rect.width.saturating_sub(1);
scrollbar_rect = Some(Rect::new(
pane_inner.x + pane_inner.width.saturating_sub(1),
pane_inner.y,
@@ -213,6 +215,39 @@ fn render_selection_highlight(
}
}
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::pane::PaneRuntime;
+ use crate::workspace::Workspace;
+
+ #[tokio::test]
+ async fn pane_scrollbar_reserves_last_column_from_terminal_area() {
+ 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,
+ PaneRuntime::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 infos = compute_pane_infos(&app, area, false);
+ let info = &infos[0];
+
+ assert_eq!(info.rect, area);
+ assert_eq!(info.scrollbar_rect, Some(Rect::new(49, 3, 1, 8)));
+ assert_eq!(info.inner_rect, Rect::new(10, 3, 39, 8));
+ }
+}
+
fn render_empty(app: &AppState, frame: &mut Frame, area: Rect) {
let p = &app.palette;
let lines = vec![