aboutsummaryrefslogtreecommitdiff
path: root/src/client/shell/mouse.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-10 16:37:50 +0300
committerGitHub <noreply@github.com>2026-09-10 16:37:50 +0300
commit90e947a6e26e02f10ec7f1694c4eb5b78a86406b (patch)
tree773c5e6e45031a55b6a32cc731944c6e65e19f33 /src/client/shell/mouse.rs
parentbf76cef889257a56b29f892816cff827b34c23da (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.rs20
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;
}
}