From a9ff4012bdca0dbdbc77bc6e53a430689fc899be Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Fri, 22 May 2026 00:12:53 +0300 Subject: feat: add configurable mouse scroll lines refs #236 --- src/app/input/mouse.rs | 55 +++++++++++++++++++++++++++++++++++++++------- src/app/input/selection.rs | 6 ++--- 2 files changed, 50 insertions(+), 11 deletions(-) (limited to 'src/app/input') diff --git a/src/app/input/mouse.rs b/src/app/input/mouse.rs index 9e54fce1..8d7fc35d 100644 --- a/src/app/input/mouse.rs +++ b/src/app/input/mouse.rs @@ -1133,7 +1133,7 @@ impl AppState { terminal_runtimes: &TerminalRuntimeRegistry, mouse: MouseEvent, ) { - const LINES_PER_NOTCH: usize = 3; + let lines_per_notch = self.mouse_scroll_lines; if let Some(info) = self.pane_at(mouse.column, mouse.row).cloned() { self.focus_pane(info.id); @@ -1142,10 +1142,10 @@ impl AppState { } match mouse.kind { MouseEventKind::ScrollUp => { - self.scroll_pane_up(terminal_runtimes, info.id, LINES_PER_NOTCH) + self.scroll_pane_up(terminal_runtimes, info.id, lines_per_notch) } MouseEventKind::ScrollDown => { - self.scroll_pane_down(terminal_runtimes, info.id, LINES_PER_NOTCH) + self.scroll_pane_down(terminal_runtimes, info.id, lines_per_notch) } _ => {} } @@ -1156,10 +1156,10 @@ impl AppState { self.focus_pane(info.id); match mouse.kind { MouseEventKind::ScrollUp => { - self.scroll_pane_up(terminal_runtimes, info.id, LINES_PER_NOTCH) + self.scroll_pane_up(terminal_runtimes, info.id, lines_per_notch) } MouseEventKind::ScrollDown => { - self.scroll_pane_down(terminal_runtimes, info.id, LINES_PER_NOTCH) + self.scroll_pane_down(terminal_runtimes, info.id, lines_per_notch) } _ => {} } @@ -1169,8 +1169,8 @@ impl AppState { if let Some(ws_idx) = self.active { if let Some(rt) = self.focused_runtime_in_workspace(terminal_runtimes, ws_idx) { match mouse.kind { - MouseEventKind::ScrollUp => rt.scroll_up(LINES_PER_NOTCH), - MouseEventKind::ScrollDown => rt.scroll_down(LINES_PER_NOTCH), + MouseEventKind::ScrollUp => rt.scroll_up(lines_per_notch), + MouseEventKind::ScrollDown => rt.scroll_down(lines_per_notch), _ => {} } } @@ -1385,7 +1385,8 @@ mod tests { use ratatui::layout::{Direction, Rect}; use super::super::{ - app_for_mouse_test, capture_snapshot, handle_context_menu_key, mouse, root_layout_ratio, + app_for_mouse_test, capture_snapshot, handle_context_menu_key, mouse, numbered_lines_bytes, + root_layout_ratio, }; use super::*; use crate::{ @@ -1394,6 +1395,44 @@ mod tests { workspace::Workspace, }; + #[tokio::test] + async fn terminal_wheel_uses_configured_mouse_scroll_lines() { + let mut app = app_for_mouse_test(); + let mut ws = Workspace::test_new("test"); + let pane_id = ws.tabs[0].root_pane; + let pane_infos = ws.tabs[0].layout.panes(Rect::new(26, 2, 80, 18)); + let info = pane_infos[0].clone(); + ws.tabs[0].runtimes.insert( + pane_id, + crate::terminal::TerminalRuntime::test_with_scrollback_bytes( + info.inner_rect.width, + info.inner_rect.height, + 16 * 1024, + &numbered_lines_bytes(64), + ), + ); + + app.state.workspaces = vec![ws]; + app.state.active = Some(0); + app.state.selected = 0; + app.state.mode = Mode::Terminal; + app.state.view.pane_infos = pane_infos; + app.state.mouse_scroll_lines = 7; + + app.handle_mouse(mouse( + MouseEventKind::ScrollUp, + info.inner_rect.x + 1, + info.inner_rect.y + 1, + )); + + let metrics = app + .state + .runtime_for_pane_in_workspace(&app.terminal_runtimes, 0, pane_id) + .and_then(crate::terminal::TerminalRuntime::scroll_metrics) + .expect("scroll metrics after wheel"); + assert_eq!(metrics.offset_from_bottom, 7); + } + #[test] fn hovering_context_menu_updates_highlight() { let mut app = app_for_mouse_test(); diff --git a/src/app/input/selection.rs b/src/app/input/selection.rs index 06de30b5..0ccb5506 100644 --- a/src/app/input/selection.rs +++ b/src/app/input/selection.rs @@ -144,7 +144,7 @@ impl AppState { terminal_runtimes: &TerminalRuntimeRegistry, mouse: MouseEvent, ) -> bool { - const LINES_PER_NOTCH: usize = 3; + let lines_per_notch = self.mouse_scroll_lines; let Some(selection) = self.selection.as_ref() else { return false; @@ -156,10 +156,10 @@ impl AppState { self.focus_pane(pane_id); match mouse.kind { MouseEventKind::ScrollUp => { - self.scroll_pane_up(terminal_runtimes, pane_id, LINES_PER_NOTCH) + self.scroll_pane_up(terminal_runtimes, pane_id, lines_per_notch) } MouseEventKind::ScrollDown => { - self.scroll_pane_down(terminal_runtimes, pane_id, LINES_PER_NOTCH) + self.scroll_pane_down(terminal_runtimes, pane_id, lines_per_notch) } _ => return false, } -- cgit v1.2.3