From 2fb76e3eeef9030db2ddf364471305a8b553f4aa Mon Sep 17 00:00:00 2001 From: Emamul Andalib Date: Tue, 23 Dec 2025 22:27:52 +0100 Subject: [PATCH] terminal: Fix fast scrolling during mouse mode Scrolling with a trackpad in tmux, neovim, or any terminal app that enables mouse mode was way too fast. A gentle swipe would send you flying through hundreds of lines. The culprit was in how we handle mouse scroll reports. When the terminal is in mouse mode, we send escape sequences to tell the app about scroll events. The problem was we sent these events even when no full line of scroll had accumulated yet. Deep in scroll_report(), there was this: repeat(report).take(max(scroll_lines, 1) as usize) That max(scroll_lines, 1) meant we'd send at least 1 scroll event even when scroll_lines was 0. On macOS, trackpad gestures fire many small pixel deltas due to scroll acceleration. Each tiny movement triggered a scroll event to tmux, even though we hadn't accumulated enough pixels for a full line yet. The fix is simple - just don't send mouse reports when scroll_lines is zero: if mouse_mode && scroll_lines != 0 { Tested with tmux, neovim, and opencode - all scroll as expected now. Closes #18930 --- crates/terminal/src/terminal.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 5d02e0220b3502..c8db9d9e6539ce 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -1988,7 +1988,9 @@ impl Terminal { let mouse_mode = self.mouse_mode(e.shift); let scroll_multiplier = if mouse_mode { 1. } else { scroll_multiplier }; - if let Some(scroll_lines) = self.determine_scroll_lines(e, scroll_multiplier) { + if let Some(scroll_lines) = self.determine_scroll_lines(e, scroll_multiplier) + && scroll_lines != 0 + { if mouse_mode { let point = grid_point( e.position - self.last_content.terminal_bounds.bounds.origin, @@ -2009,7 +2011,7 @@ impl Terminal { && !e.shift { self.write_to_pty(alt_scroll(scroll_lines)); - } else if scroll_lines != 0 { + } else { let scroll = AlacScroll::Delta(scroll_lines); self.events.push_back(InternalEvent::Scroll(scroll));