From e43c6a23b12ea5459481bfded1ae9c19cd0ea369 Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Sat, 4 Jan 2025 13:21:38 -0500 Subject: [PATCH] feat: add stop_listen for mac --- examples/simply_listen.rs | 25 +++++++++++++++++++++++++ src/lib.rs | 16 ++++++++++++---- src/macos/listen.rs | 18 ++++++++++++++++-- src/macos/mod.rs | 2 +- 4 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 examples/simply_listen.rs diff --git a/examples/simply_listen.rs b/examples/simply_listen.rs new file mode 100644 index 00000000..9aa7d322 --- /dev/null +++ b/examples/simply_listen.rs @@ -0,0 +1,25 @@ +use rdev::{listen, Event, EventType}; + +fn callback(event: Event) { + match event.event_type { + EventType::KeyPress(_key) | EventType::KeyRelease(_key) => { + println!("User wrote {:?}", event.unicode); + } + _ => (), + } +} + +fn main() { + // This will block. + use std::thread; + use std::time::Duration; + let handle = thread::spawn(|| { + if let Err(error) = listen(callback) { + println!("Error: {:?}", error) + } + }); + thread::sleep(Duration::from_secs(5)); + rdev::stop_listen().unwrap(); + let _ = handle.join(); + println!("Done"); +} diff --git a/src/lib.rs b/src/lib.rs index 4832560a..941aa1fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -238,6 +238,9 @@ pub use crate::codes_conv::*; pub use keycodes::android::{ code_from_key as android_keycode_from_key, key_from_code as android_key_from_code, }; +pub use keycodes::chrome::{ + code_from_key as chrome_keycode_from_key, key_from_code as chrome_key_from_code, +}; pub use keycodes::linux::{ code_from_key as linux_keycode_from_key, key_from_code as linux_key_from_code, }; @@ -252,14 +255,14 @@ pub use keycodes::windows::{ get_win_key, key_from_code as win_key_from_keycode, key_from_scancode as win_key_from_scancode, scancode_from_key as win_scancode_from_key, }; -pub use keycodes::chrome::{ - code_from_key as chrome_keycode_from_key, key_from_code as chrome_key_from_code, -}; #[cfg(target_os = "macos")] pub use crate::keycodes::macos::{code_from_key, key_from_code, virtual_keycodes::*}; #[cfg(target_os = "macos")] -use crate::macos::{display_size as _display_size, listen as _listen, simulate as _simulate}; +use crate::macos::{ + display_size as _display_size, listen as _listen, simulate as _simulate, + stop_listen as _stop_listen, +}; #[cfg(target_os = "macos")] pub use crate::macos::{set_is_main_thread, Keyboard, VirtualInput}; #[cfg(target_os = "macos")] @@ -312,6 +315,11 @@ where _listen(callback) } +#[cfg(target_os = "macos")] +pub fn stop_listen() -> Result<(), ListenError> { + _stop_listen() +} + /// Sending some events /// /// ```no_run diff --git a/src/macos/listen.rs b/src/macos/listen.rs index 6ca4098a..e84683af 100644 --- a/src/macos/listen.rs +++ b/src/macos/listen.rs @@ -30,6 +30,8 @@ unsafe extern "C" fn raw_callback( cg_event } +static mut CUR_LOOP: CFRunLoopSourceRef = std::ptr::null_mut(); + pub fn listen(callback: T) -> Result<(), ListenError> where T: FnMut(Event) + 'static, @@ -59,11 +61,23 @@ where return Err(ListenError::LoopSourceError); } - let current_loop = CFRunLoopGetMain(); - CFRunLoopAddSource(current_loop, _loop, kCFRunLoopCommonModes); + CUR_LOOP = CFRunLoopGetCurrent() as _; + CFRunLoopAddSource(CUR_LOOP, _loop, kCFRunLoopCommonModes); + // let current_loop = CFRunLoopGetMain(); + // CFRunLoopAddSource(current_loop, _loop, kCFRunLoopCommonModes); CGEventTapEnable(tap, true); CFRunLoopRun(); } Ok(()) } + +pub fn stop_listen() -> Result<(), ListenError> { + unsafe { + if !CUR_LOOP.is_null() { + CFRunLoopStop(CUR_LOOP); + CUR_LOOP = std::ptr::null_mut(); + } + } + Ok(()) +} diff --git a/src/macos/mod.rs b/src/macos/mod.rs index eedc332f..7ec0530a 100644 --- a/src/macos/mod.rs +++ b/src/macos/mod.rs @@ -9,7 +9,7 @@ pub use crate::macos::common::{map_keycode, set_is_main_thread}; pub use crate::macos::display::display_size; pub use crate::macos::grab::{exit_grab, grab, is_grabbed}; pub use crate::macos::keyboard::Keyboard; -pub use crate::macos::listen::listen; +pub use crate::macos::listen::{listen, stop_listen}; pub use crate::macos::simulate::{ set_keyboard_extra_info, set_mouse_extra_info, simulate, VirtualInput, };