From 260c924010361137dd67be145e9d5c0850804768 Mon Sep 17 00:00:00 2001 From: xxrl <837951112@qq.com> Date: Mon, 7 Nov 2022 01:25:36 +0800 Subject: [PATCH] opt: mac scroll to fast --- libs/enigo/src/macos/macos_impl.rs | 57 ++++++++++++++++++++++++++++++ src/client.rs | 23 ++++++++++++ src/server/input_service.rs | 41 +++++++++++++++------ 3 files changed, 111 insertions(+), 10 deletions(-) diff --git a/libs/enigo/src/macos/macos_impl.rs b/libs/enigo/src/macos/macos_impl.rs index 520c9dca1..fb9c2d680 100644 --- a/libs/enigo/src/macos/macos_impl.rs +++ b/libs/enigo/src/macos/macos_impl.rs @@ -580,6 +580,63 @@ impl Enigo { _ => u16::MAX, } } + + #[inline] + fn mouse_scroll_impl(&mut self, length: i32, is_track_pad: bool, is_horizontal: bool) { + let mut scroll_direction = -1; // 1 left -1 right; + let mut length = length; + + if length < 0 { + length *= -1; + scroll_direction *= -1; + } + + // fix scroll distance for track pad + if is_track_pad { + length *= 3; + } + + if let Some(src) = self.event_source.as_ref() { + for _ in 0..length { + unsafe { + let units = if is_track_pad { + ScrollUnit::Pixel + } else { + ScrollUnit::Line + }; + let mouse_ev = if is_horizontal { + CGEventCreateScrollWheelEvent( + &src, + units, + 2, // CGWheelCount 1 = y 2 = xy 3 = xyz + 0, + scroll_direction, + ) + } else { + CGEventCreateScrollWheelEvent( + &src, + units, + 1, // CGWheelCount 1 = y 2 = xy 3 = xyz + scroll_direction, + ) + }; + + CGEventPost(CGEventTapLocation::HID, mouse_ev); + CFRelease(mouse_ev as *const std::ffi::c_void); + } + } + } + } + + /// handle scroll vertically + pub fn mouse_scroll_y(&mut self, length: i32, is_track_pad: bool) { + self.mouse_scroll_impl(length, is_track_pad, false) + } + + /// handle scroll horizontally + pub fn mouse_scroll_x(&mut self, length: i32, is_track_pad: bool) { + self.mouse_scroll_impl(length, is_track_pad, true) + } } #[inline] diff --git a/src/client.rs b/src/client.rs index d00df1c48..2be71828d 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1529,6 +1529,25 @@ pub async fn handle_test_delay(t: TestDelay, peer: &mut Stream) { } } +#[inline] +#[cfg(target_os = "macos")] +fn check_scroll_on_mac(mask: i32, x: i32, y: i32) -> bool { + if mask & 3 != 3 { + return false; + } + let btn = mask >> 3; + if y == -1 { + btn != 0xff88 && btn != -0x780000 + } else if y == 1 { + btn != 0x78 && btn != 0x780000 + } else if x != 0 { + // No mouse support horizontal scrolling. + true + } else { + false + } +} + /// Send mouse data. /// /// # Arguments @@ -1574,6 +1593,10 @@ pub fn send_mouse( if command { mouse_event.modifiers.push(ControlKey::Meta.into()); } + #[cfg(target_os = "macos")] + if check_scroll_on_mac(mask, x, y) { + mouse_event.modifiers.push(ControlKey::Scroll.into()); + } msg_out.set_mouse_event(mouse_event); interface.send(Data::Message(msg_out)); } diff --git a/src/server/input_service.rs b/src/server/input_service.rs index d91e9a799..ac46726ac 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -429,18 +429,39 @@ fn handle_mouse_(evt: &MouseEvent, conn: i32) { x = -x; y = -y; } - - // fix shift + scroll(down/up) #[cfg(target_os = "macos")] - if evt.modifiers.contains(&EnumOrUnknown::new(ControlKey::Shift)){ - x = y; - y = 0; + { + // TODO: support track pad on win. + let is_track_pad = evt + .modifiers + .contains(&EnumOrUnknown::new(ControlKey::Scroll)); + + // fix shift + scroll(down/up) + if !is_track_pad + && evt + .modifiers + .contains(&EnumOrUnknown::new(ControlKey::Shift)) + { + x = y; + y = 0; + } + + if x != 0 { + en.mouse_scroll_x(x, is_track_pad); + } + if y != 0 { + en.mouse_scroll_y(y, is_track_pad); + } } - if x != 0 { - en.mouse_scroll_x(x); - } - if y != 0 { - en.mouse_scroll_y(y); + + #[cfg(not(target_os = "macos"))] + { + if x != 0 { + en.mouse_scroll_x(x); + } + if y != 0 { + en.mouse_scroll_y(y); + } } } _ => {}