diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-10 16:37:50 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-10 16:37:50 +0300 |
| commit | 90e947a6e26e02f10ec7f1694c4eb5b78a86406b (patch) | |
| tree | 773c5e6e45031a55b6a32cc731944c6e65e19f33 /src/client/shell/mouse.rs | |
| parent | bf76cef889257a56b29f892816cff827b34c23da (diff) | |
fix: bound mouse selection repaint cadence (#3901)
refs #3895
Diffstat (limited to 'src/client/shell/mouse.rs')
| -rw-r--r-- | src/client/shell/mouse.rs | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/src/client/shell/mouse.rs b/src/client/shell/mouse.rs index 24310907..af324174 100644 --- a/src/client/shell/mouse.rs +++ b/src/client/shell/mouse.rs @@ -2,6 +2,7 @@ use super::*; use crossterm::event::{MouseButton, MouseEvent, MouseEventKind}; const SELECTION_AUTOSCROLL_INTERVAL: std::time::Duration = std::time::Duration::from_millis(30); +const SELECTION_REPAINT_INTERVAL: std::time::Duration = std::time::Duration::from_millis(16); impl ClientShellState { fn set_sidebar_width_from_column(&mut self, column: u16, outcome: &mut ClientShellInput) { @@ -313,12 +314,27 @@ impl ClientShellState { true } + pub(super) fn request_selection_drag_repaint(&mut self, now: std::time::Instant) -> bool { + let deadline = self + .last_composed_at + .map(|last| last + SELECTION_REPAINT_INTERVAL); + self.selection_repaint_deadline = deadline.filter(|deadline| now < *deadline); + self.selection_repaint_deadline.is_none() + } + pub(crate) fn tick_selection_autoscroll( &mut self, now: std::time::Instant, ) -> ClientShellInput { let mut outcome = ClientShellInput::default(); if self + .selection_repaint_deadline + .is_some_and(|deadline| now >= deadline) + { + self.selection_repaint_deadline = None; + outcome.repaint = true; + } + if self .selection_autoscroll_deadline .is_none_or(|deadline| now < deadline) { @@ -1652,7 +1668,9 @@ impl ClientShellState { }); if let Some(hit) = selection_hit { self.update_selection_drag(&hit, mouse.column, mouse.row, outcome); - outcome.repaint = true; + // Consume every motion, but do not rebuild a frame for every intermediate position. + outcome.repaint |= !outcome.actions.is_empty() + || self.request_selection_drag_repaint(std::time::Instant::now()); return; } } |
