diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-03-31 20:49:05 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-03-31 20:49:05 +0300 |
| commit | 41e009f9b7b46d335d41b365e41f9ad57d571ecb (patch) | |
| tree | 42b3be90c336ad6d4487e9f86abc56ebb40ba210 /src/app | |
| parent | f826fb78dcac89b4ba23e399ac5d141459c14ae9 (diff) | |
fix alt-screen scrollback handling
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/input.rs | 66 | ||||
| -rw-r--r-- | src/app/state.rs | 1 |
2 files changed, 52 insertions, 15 deletions
diff --git a/src/app/input.rs b/src/app/input.rs index 9827d4d2..05667ab9 100644 --- a/src/app/input.rs +++ b/src/app/input.rs @@ -10,6 +10,12 @@ use tracing::warn; use crate::layout::{NavDirection, PaneInfo, SplitBorder}; use crate::selection::Selection; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum ScrollbarClickTarget { + Thumb { grab_row_offset: u16 }, + Track { offset_from_bottom: usize }, +} + use super::state::{ key_matches, AppState, ContextMenuKind, ContextMenuState, DragState, DragTarget, Mode, }; @@ -926,14 +932,23 @@ impl AppState { return None; } - if let Some((pane_id, offset_from_bottom)) = + if let Some((pane_id, target)) = self.scrollbar_target_at(mouse.column, mouse.row) { self.focus_pane(pane_id); - self.set_pane_scroll_offset(pane_id, offset_from_bottom); - self.drag = Some(DragState { - target: DragTarget::PaneScrollbar { pane_id }, - }); + match target { + ScrollbarClickTarget::Thumb { grab_row_offset } => { + self.drag = Some(DragState { + target: DragTarget::PaneScrollbar { + pane_id, + grab_row_offset, + }, + }); + } + ScrollbarClickTarget::Track { offset_from_bottom } => { + self.set_pane_scroll_offset(pane_id, offset_from_bottom); + } + } if self.mode != Mode::Terminal { self.mode = Mode::Terminal; } @@ -1022,10 +1037,15 @@ impl AppState { ws.layout.set_ratio_at(&path, ratio); } } - DragTarget::PaneScrollbar { pane_id } => { - if let Some(offset_from_bottom) = - self.scrollbar_offset_for_pane_row(*pane_id, mouse.row) - { + DragTarget::PaneScrollbar { + pane_id, + grab_row_offset, + } => { + if let Some(offset_from_bottom) = self.scrollbar_offset_for_pane_row( + *pane_id, + mouse.row, + *grab_row_offset, + ) { self.set_pane_scroll_offset(*pane_id, offset_from_bottom); } } @@ -1331,7 +1351,11 @@ impl AppState { } } - fn scrollbar_target_at(&self, col: u16, row: u16) -> Option<(crate::layout::PaneId, usize)> { + fn scrollbar_target_at( + &self, + col: u16, + row: u16, + ) -> Option<(crate::layout::PaneId, ScrollbarClickTarget)> { let ws = self.active.and_then(|i| self.workspaces.get(i))?; let info = self.view.pane_infos.iter().find(|info| { crate::ui::pane_scrollbar_rect(info).is_some_and(|track| { @@ -1347,16 +1371,23 @@ impl AppState { return None; } let track = crate::ui::pane_scrollbar_rect(info)?; - Some(( - info.id, - crate::ui::scrollbar_offset_from_row(metrics, track, row), - )) + if let Some(grab_row_offset) = crate::ui::scrollbar_thumb_grab_offset(metrics, track, row) { + Some((info.id, ScrollbarClickTarget::Thumb { grab_row_offset })) + } else { + Some(( + info.id, + ScrollbarClickTarget::Track { + offset_from_bottom: crate::ui::scrollbar_offset_from_row(metrics, track, row), + }, + )) + } } fn scrollbar_offset_for_pane_row( &self, pane_id: crate::layout::PaneId, row: u16, + grab_row_offset: u16, ) -> Option<usize> { let ws = self.active.and_then(|i| self.workspaces.get(i))?; let info = self @@ -1370,7 +1401,12 @@ impl AppState { if metrics.max_offset_from_bottom == 0 { return None; } - Some(crate::ui::scrollbar_offset_from_row(metrics, track, row)) + Some(crate::ui::scrollbar_offset_from_drag_row( + metrics, + track, + row, + grab_row_offset, + )) } } diff --git a/src/app/state.rs b/src/app/state.rs index caedb419..cd45bbb6 100644 --- a/src/app/state.rs +++ b/src/app/state.rs @@ -397,6 +397,7 @@ pub(crate) enum DragTarget { }, PaneScrollbar { pane_id: crate::layout::PaneId, + grab_row_offset: u16, }, SidebarDivider, } |
