Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions src-tauri/src/mouse_repeat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,37 @@ pub struct ScanMoveRepeat {
movement: MoveRepeatState,
}

/// The scanned scroll control uses Remote's immediate first step followed by
/// one step per configured interval. A delayed scanner tick never bursts
/// multiple scroll events into the foreground app.
pub struct ScanScrollRepeat {
direction: i8,
elapsed_ms: u64,
}

impl ScanScrollRepeat {
pub fn new(direction: i8) -> Self {
Self {
direction,
elapsed_ms: 0,
}
}

pub fn dy(&self) -> i32 {
i32::from(self.direction) * 5
}

pub fn advance(&mut self, elapsed_ms: u64, interval_ms: u32) -> bool {
let interval = u64::from(interval_ms.max(1));
self.elapsed_ms = self.elapsed_ms.saturating_add(elapsed_ms);
if self.elapsed_ms < interval {
return false;
}
self.elapsed_ms %= interval;
true
}
}

impl ScanMoveRepeat {
pub fn new(dx: i32, dy: i32, now: Instant) -> Self {
Self {
Expand Down Expand Up @@ -704,6 +735,19 @@ mod tests {
assert!((647..=649).contains(&distance));
}

#[test]
fn scanned_scroll_uses_remote_step_and_interval_without_bursting() {
let mut repeat = ScanScrollRepeat::new(-1);
assert_eq!(repeat.dy(), -5);
assert!(!repeat.advance(79, 80));
assert!(repeat.advance(1, 80));
assert!(!repeat.advance(40, 80));
assert!(repeat.advance(40, 80));
assert!(repeat.advance(250, 80));
assert!(!repeat.advance(69, 80));
assert!(repeat.advance(1, 80));
}

#[test]
fn parses_only_bounded_move_and_scroll_commands() {
assert_eq!(
Expand Down
19 changes: 17 additions & 2 deletions src-tauri/src/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,18 @@ impl OverlayEngine {
settings.cursor_overlay_enabled = true;
settings.cursor_overlay_visibility = "whileControlling".into();
let update = self.handle(Command::Show(feedback, settings), now);
if dragging && matches!(feedback, PointerFeedback::Scroll { .. }) {
if dragging
&& matches!(
feedback,
PointerFeedback::Scroll { .. } | PointerFeedback::RepeatScroll { .. }
)
{
self.drag_active = true;
}
if matches!(feedback, PointerFeedback::RepeatMove { .. }) {
if matches!(
feedback,
PointerFeedback::RepeatMove { .. } | PointerFeedback::RepeatScroll { .. }
) {
self.deadline = None;
}
update
Expand Down Expand Up @@ -1094,6 +1102,13 @@ mod tests {
now,
);
assert_eq!(engine.deadline, None);
engine.show_scan_mouse(
PointerFeedback::RepeatScroll { dx: 0, dy: 5 },
settings.clone(),
now,
);
assert_eq!(engine.deadline, None);
assert!(engine.drag_active);
engine.show_scan_mouse(PointerFeedback::Drag, settings, now);
assert!(matches!(engine.end_scan_mouse(now), Update::Hide));
assert!(!engine.visible);
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/src/point_scan_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ impl Adapter for PointScan {
settings.pointer_scale_percent,
settings.mouse_repeat_acceleration_duration_ms,
settings.move_repeat_interval_ms,
settings.scroll_repeat_interval_ms,
settings.mouse_repeat_enabled,
);
} else if technique.keyboard_open() {
Expand All @@ -244,6 +245,7 @@ impl Adapter for PointScan {
| Request::Prediction { .. }
| Request::MouseMove { .. }
| Request::MouseMoveAbsolute { .. }
| Request::MouseScroll { .. }
)
}
fn deferred(request: &Request) -> bool {
Expand Down Expand Up @@ -387,6 +389,7 @@ mod tests {
token: 1,
index: 0
}));
assert!(PointScan::preserve_visuals(&Request::MouseScroll { dy: 5 }));
assert!(!PointScan::preserve_visuals(
&crate::point_workflow::default_click((10, 20))
));
Expand Down
Loading
Loading