diff --git a/examples/simulate.rs b/examples/simulate.rs index 1f50f042..14df9ab5 100644 --- a/examples/simulate.rs +++ b/examples/simulate.rs @@ -1,4 +1,4 @@ -use rdev::{simulate, Button, EventType, Key, SimulateError}; +use rdev::{simulate, Button, EventType, Key, MouseScrollDelta, SimulateError}; use std::{thread, time}; fn send(event_type: &EventType) { @@ -21,8 +21,5 @@ fn main() { send(&EventType::MouseMove { x: 400.0, y: 400.0 }); send(&EventType::ButtonPress(Button::Left)); send(&EventType::ButtonRelease(Button::Right)); - send(&EventType::Wheel { - delta_x: 0, - delta_y: 1, - }); + send(&EventType::Wheel(MouseScrollDelta::LineDelta(0.0, 1.0))); } diff --git a/src/lib.rs b/src/lib.rs index 64efbe40..2706e2be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ //! # Sending some events //! //! ```no_run -//! use rdev::{simulate, Button, EventType, Key, SimulateError}; +//! use rdev::{simulate, Button, EventType, MouseScrollDelta, Key, SimulateError}; //! use std::{thread, time}; //! //! fn send(event_type: &EventType) { @@ -64,10 +64,7 @@ //! send(&EventType::MouseMove { x: 400.0, y: 400.0 }); //! send(&EventType::ButtonPress(Button::Left)); //! send(&EventType::ButtonRelease(Button::Right)); -//! send(&EventType::Wheel { -//! delta_x: 0, -//! delta_y: 1, -//! }); +//! send(&EventType::Wheel(MouseScrollDelta::LineDelta(0.0, 1.0))); //! ``` //! # Main structs //! ## Event @@ -220,7 +217,7 @@ mod rdev; pub use crate::rdev::{ Button, DisplayError, Event, EventType, GrabCallback, GrabError, Key, KeyboardState, - ListenError, SimulateError, + ListenError, MouseScrollDelta, SimulateError, }; #[cfg(target_os = "macos")] @@ -275,7 +272,7 @@ where /// Sending some events /// /// ```no_run -/// use rdev::{simulate, Button, EventType, Key, SimulateError}; +/// use rdev::{simulate, Button, EventType,MouseScrollDelta, Key, SimulateError}; /// use std::{thread, time}; /// /// fn send(event_type: &EventType) { @@ -298,10 +295,7 @@ where /// send(&EventType::MouseMove { x: 400.0, y: 400.0 }); /// send(&EventType::ButtonPress(Button::Left)); /// send(&EventType::ButtonRelease(Button::Right)); -/// send(&EventType::Wheel { -/// delta_x: 0, -/// delta_y: 1, -/// }); +/// send(&EventType::Wheel(MouseScrollDelta::LineDelta(0.0, 1.0))); /// } /// ``` pub fn simulate(event_type: &EventType) -> Result<(), SimulateError> { @@ -357,11 +351,17 @@ pub use crate::windows::grab as _grab; /// } /// ``` #[cfg(feature = "unstable_grab")] -pub fn grab(callback: T) -> Result<(), GrabError> +pub fn grab(event_types: EventTypes, callback: T) -> Result<(), GrabError> where T: Fn(Event) -> Option + 'static, { - _grab(callback) + _grab(event_types, callback) +} + +#[cfg(feature = "unstable_grab")] +pub struct EventTypes { + pub keyboard: bool, + pub mouse: bool, } #[cfg(test)] diff --git a/src/rdev.rs b/src/rdev.rs index 277be3b0..7b8537a1 100644 --- a/src/rdev.rs +++ b/src/rdev.rs @@ -244,10 +244,14 @@ pub enum EventType { /// `delta_y` represents vertical scroll and `delta_x` represents horizontal scroll. /// Positive values correspond to scrolling up or right and negative values /// correspond to scrolling down or left - Wheel { - delta_x: i64, - delta_y: i64, - }, + Wheel(MouseScrollDelta), +} + +#[derive(Debug, Copy, Clone, PartialEq)] +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] +pub enum MouseScrollDelta { + LineDelta(f32, f32), + // Not supported yet PixelDelta(PhysicalPosition), } /// When events arrive from the OS they get some additional information added from diff --git a/src/windows/common.rs b/src/windows/common.rs index a7579c52..7fe249ea 100644 --- a/src/windows/common.rs +++ b/src/windows/common.rs @@ -1,4 +1,4 @@ -use crate::rdev::{Button, EventType}; +use crate::rdev::{Button, EventType, MouseScrollDelta}; use crate::windows::keyboard::Keyboard; use crate::windows::keycodes::key_from_code; use lazy_static::lazy_static; @@ -83,17 +83,17 @@ pub unsafe fn convert(param: WPARAM, lpdata: LPARAM) -> Option { } Ok(WM_MOUSEWHEEL) => { let delta = get_delta(lpdata) as c_short; - Some(EventType::Wheel { - delta_x: 0, - delta_y: (delta / WHEEL_DELTA) as i64, - }) + Some(EventType::Wheel(MouseScrollDelta::LineDelta( + 0.0, + delta as f32 / WHEEL_DELTA as f32, + ))) } Ok(WM_MOUSEHWHEEL) => { let delta = get_delta(lpdata) as c_short; - Some(EventType::Wheel { - delta_x: (delta / WHEEL_DELTA) as i64, - delta_y: 0, - }) + Some(EventType::Wheel(MouseScrollDelta::LineDelta( + 0.0, + delta as f32 / WHEEL_DELTA as f32, + ))) } _ => None, } diff --git a/src/windows/grab.rs b/src/windows/grab.rs index cd1930f2..9b06b46c 100644 --- a/src/windows/grab.rs +++ b/src/windows/grab.rs @@ -1,5 +1,6 @@ use crate::rdev::{Event, EventType, GrabError}; use crate::windows::common::{convert, set_key_hook, set_mouse_hook, HookError, HOOK, KEYBOARD}; +use crate::EventTypes; use std::ptr::null_mut; use std::time::SystemTime; use winapi::um::winuser::{CallNextHookEx, GetMessageA, HC_ACTION}; @@ -44,15 +45,18 @@ impl From for GrabError { } } -pub fn grab(callback: T) -> Result<(), GrabError> +pub fn grab(event_types: EventTypes, callback: T) -> Result<(), GrabError> where T: FnMut(Event) -> Option + 'static, { unsafe { GLOBAL_CALLBACK = Some(Box::new(callback)); - set_key_hook(raw_callback)?; - set_mouse_hook(raw_callback)?; - + if event_types.keyboard { + set_key_hook(raw_callback)?; + } + if event_types.mouse { + set_mouse_hook(raw_callback)?; + } GetMessageA(null_mut(), null_mut(), 0, 0); } Ok(()) diff --git a/src/windows/simulate.rs b/src/windows/simulate.rs index cd62e220..bf030031 100644 --- a/src/windows/simulate.rs +++ b/src/windows/simulate.rs @@ -1,4 +1,4 @@ -use crate::rdev::{Button, EventType, SimulateError}; +use crate::rdev::{Button, EventType, MouseScrollDelta, SimulateError}; use crate::windows::keycodes::code_from_key; use std::convert::TryFrom; use std::mem::size_of; @@ -95,20 +95,22 @@ pub fn simulate(event_type: &EventType) -> Result<(), SimulateError> { Button::Right => sim_mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0), Button::Unknown(code) => sim_mouse_event(MOUSEEVENTF_XUP, (*code).into(), 0, 0), }, - EventType::Wheel { delta_x, delta_y } => { - if *delta_x != 0 { + EventType::Wheel(MouseScrollDelta::LineDelta(delta_x, delta_y)) => { + if *delta_x != 0.0 { + let delta_x = *delta_x * WHEEL_DELTA as f32; sim_mouse_event( MOUSEEVENTF_HWHEEL, - (c_short::try_from(*delta_x).map_err(|_| SimulateError)? * WHEEL_DELTA) as u32, + (c_short::try_from(delta_x as i16).map_err(|_| SimulateError)?) as u32, 0, 0, )?; } - if *delta_y != 0 { + if *delta_y != 0.0 { + let delta_y = *delta_y * WHEEL_DELTA as f32; sim_mouse_event( MOUSEEVENTF_WHEEL, - (c_short::try_from(*delta_y).map_err(|_| SimulateError)? * WHEEL_DELTA) as u32, + (c_short::try_from(delta_y as i16).map_err(|_| SimulateError)?) as u32, 0, 0, )?; diff --git a/tests/grab.rs b/tests/grab.rs index a3fad1e8..9b561d73 100644 --- a/tests/grab.rs +++ b/tests/grab.rs @@ -1,5 +1,5 @@ use lazy_static::lazy_static; -use rdev::{grab, listen, simulate, Event, EventType, Key}; +use rdev::{grab, listen, simulate, Event, EventType, EventTypes, Key}; use serial_test::serial; use std::error::Error; use std::sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender}; @@ -45,7 +45,14 @@ fn test_grab() -> Result<(), Box> { // Make sure grab ends up on top of listen so it can properly discard. thread::sleep(Duration::from_secs(1)); let _grab = thread::spawn(move || { - grab(grab_tab).expect("Could not grab"); + grab( + EventTypes { + keyboard: true, + mouse: true, + }, + grab_tab, + ) + .expect("Could not grab"); }); let recv = EVENT_CHANNEL.1.lock().expect("Failed to unlock Mutex"); diff --git a/tests/listen_and_simulate.rs b/tests/listen_and_simulate.rs index 03b9809d..132427e5 100644 --- a/tests/listen_and_simulate.rs +++ b/tests/listen_and_simulate.rs @@ -1,5 +1,5 @@ use lazy_static::lazy_static; -use rdev::{listen, simulate, Button, Event, EventType, Key}; +use rdev::{listen, simulate, Button, Event, EventType, Key, MouseScrollDelta}; use serial_test::serial; use std::error::Error; use std::iter::Iterator; @@ -55,14 +55,8 @@ fn test_listen_and_simulate() -> Result<(), Box> { EventType::KeyRelease(Key::KeyS), EventType::ButtonPress(Button::Right), EventType::ButtonRelease(Button::Right), - EventType::Wheel { - delta_x: 0, - delta_y: 1, - }, - EventType::Wheel { - delta_x: 0, - delta_y: -1, - }, + EventType::Wheel(MouseScrollDelta::LineDelta(0.0, 1.0)), + EventType::Wheel(MouseScrollDelta::LineDelta(0.0, -1.0)), ] .into_iter(); let click_events = (0..480).map(|pixel| EventType::MouseMove {