diff --git a/Cargo.toml b/Cargo.toml index 6f378640..743bed30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ cocoa = "0.22" core-graphics = {version = "0.19.0", features = ["highsierra"]} core-foundation = {version = "0.7"} core-foundation-sys = {version = "0.7"} +dispatch = "0.2" [target.'cfg(target_os = "linux")'.dependencies] diff --git a/src/lib.rs b/src/lib.rs index 64efbe40..b80a6253 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -226,7 +226,7 @@ pub use crate::rdev::{ #[cfg(target_os = "macos")] mod macos; #[cfg(target_os = "macos")] -pub use crate::macos::Keyboard; +pub use crate::macos::{set_is_main_thread, Keyboard}; #[cfg(target_os = "macos")] use crate::macos::{display_size as _display_size, listen as _listen, simulate as _simulate}; diff --git a/src/macos/common.rs b/src/macos/common.rs index 6c837ab0..945b1153 100644 --- a/src/macos/common.rs +++ b/src/macos/common.rs @@ -91,6 +91,10 @@ pub type QCallback = unsafe extern "C" fn( user_info: *mut c_void, ) -> CGEventRef; +pub fn set_is_main_thread(b: bool) { + KEYBOARD_STATE.lock().unwrap().set_is_main_thread(b); +} + pub unsafe fn convert( _type: CGEventType, cg_event: &CGEvent, diff --git a/src/macos/keyboard.rs b/src/macos/keyboard.rs index 131ef478..ab4c0485 100644 --- a/src/macos/keyboard.rs +++ b/src/macos/keyboard.rs @@ -31,6 +31,10 @@ static NSEventModifierFlagCommand: u64 = 1 << 20; const BUF_LEN: usize = 4; +lazy_static::lazy_static! { + static ref QUEUE: dispatch::Queue = dispatch::Queue::main(); +} + #[cfg(target_os = "macos")] #[link(name = "Cocoa", kind = "framework")] #[link(name = "Carbon", kind = "framework")] @@ -56,6 +60,7 @@ extern "C" { } pub struct Keyboard { + is_main_thread: bool, dead_state: u32, shift: bool, caps_lock: bool, @@ -63,12 +68,17 @@ pub struct Keyboard { impl Keyboard { pub fn new() -> Option { Some(Keyboard { + is_main_thread: true, dead_state: 0, shift: false, caps_lock: false, }) } + pub fn set_is_main_thread(&mut self, b: bool) { + self.is_main_thread = b; + } + fn modifier_state(&self) -> ModifierState { if self.caps_lock || self.shift { 2 @@ -83,7 +93,15 @@ impl Keyboard { flags: CGEventFlags, ) -> Option { let modifier_state = flags_to_state(flags.bits()); - self.string_from_code(code, modifier_state) + + if self.is_main_thread { + self.string_from_code(code, modifier_state) + } else { + QUEUE.exec_sync(move || { + // ignore all modifiers for name + self.string_from_code(code, modifier_state) + }) + } } pub(crate) unsafe fn string_from_code( diff --git a/src/macos/mod.rs b/src/macos/mod.rs index 43ce23fb..87326541 100644 --- a/src/macos/mod.rs +++ b/src/macos/mod.rs @@ -7,6 +7,7 @@ mod keycodes; mod listen; mod simulate; +pub use crate::macos::common::set_is_main_thread; pub use crate::macos::display::display_size; #[cfg(feature = "unstable_grab")] pub use crate::macos::grab::grab;