Skip to content

Commit

Permalink
macos: Send the correct event flags when an event gets posted
Browse files Browse the repository at this point in the history
Set the correct event flags when pressing a modifier or a key from the numpad.
Send the currently set event flags each time an event gets posted.
  • Loading branch information
pentamassiv committed Oct 26, 2024
1 parent 4492020 commit 83202ea
Showing 1 changed file with 66 additions and 4 deletions.
70 changes: 66 additions & 4 deletions src/macos/macos_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub struct Enigo {
held: (Vec<Key>, Vec<CGKeyCode>), // Currently held keys
event_source_user_data: i64,
release_keys_when_dropped: bool,
event_flags: CGEventFlags,
double_click_delay: Duration,
// TODO: Use mem::variant_count::<Button>() here instead of 7 once it is stabilized
last_mouse_click: [(i64, Instant); 7], /* For each of the seven Button variants, we
Expand Down Expand Up @@ -119,7 +120,7 @@ impl Mouse for Enigo {
EventField::EVENT_SOURCE_USER_DATA,
self.event_source_user_data,
);
event.set_flags(CGEventFlags::CGEventFlagNonCoalesced);
event.set_flags(self.event_flags);
event.post(CGEventTapLocation::HID);
}
if direction == Direction::Click || direction == Direction::Release {
Expand Down Expand Up @@ -150,7 +151,7 @@ impl Mouse for Enigo {
EventField::EVENT_SOURCE_USER_DATA,
self.event_source_user_data,
);
event.set_flags(CGEventFlags::CGEventFlagNonCoalesced);
event.set_flags(self.event_flags);
event.post(CGEventTapLocation::HID);
}
Ok(())
Expand Down Expand Up @@ -200,7 +201,7 @@ impl Mouse for Enigo {
EventField::EVENT_SOURCE_USER_DATA,
self.event_source_user_data,
);
event.set_flags(CGEventFlags::CGEventFlagNonCoalesced);
event.set_flags(self.event_flags);
event.post(CGEventTapLocation::HID);
Ok(())
}
Expand Down Expand Up @@ -228,7 +229,7 @@ impl Mouse for Enigo {
EventField::EVENT_SOURCE_USER_DATA,
self.event_source_user_data,
);
event.set_flags(CGEventFlags::CGEventFlagNonCoalesced);
event.set_flags(self.event_flags);
event.post(CGEventTapLocation::HID);
Ok(())
}
Expand Down Expand Up @@ -309,6 +310,8 @@ impl Keyboard for Enigo {
EventField::EVENT_SOURCE_USER_DATA,
self.event_source_user_data,
);
event.set_flags(self.event_flags); // TODO: Check if this is a good idea (maybe use CGEventFlags::CGEventFlagNull
// here?)
event.post(CGEventTapLocation::HID);
}
Ok(Some(()))
Expand Down Expand Up @@ -441,6 +444,8 @@ impl Keyboard for Enigo {
EventField::EVENT_SOURCE_USER_DATA,
self.event_source_user_data,
);
self.add_event_flag(keycode, Direction::Press);
event.set_flags(self.event_flags);
event.post(CGEventTapLocation::HID);
}

Expand All @@ -456,6 +461,8 @@ impl Keyboard for Enigo {
EventField::EVENT_SOURCE_USER_DATA,
self.event_source_user_data,
);
self.add_event_flag(keycode, Direction::Release);
event.set_flags(self.event_flags);
event.post(CGEventTapLocation::HID);
}

Expand Down Expand Up @@ -499,6 +506,8 @@ impl Enigo {

let held = (Vec::new(), Vec::new());

let event_flags = CGEventFlags::CGEventFlagNonCoalesced;

let double_click_delay = Duration::from_secs(1);
let double_click_delay_setting = unsafe { NSEvent::doubleClickInterval() };
// Returns the double click interval (https://developer.apple.com/documentation/appkit/nsevent/1528384-doubleclickinterval). This is a TimeInterval which is a f64 of the number of seconds
Expand All @@ -520,6 +529,7 @@ impl Enigo {
display: CGDisplay::main(),
held,
release_keys_when_dropped: *release_keys_when_dropped,
event_flags,
double_click_delay,
last_mouse_click: [(0, Instant::now()); 7],
event_source_user_data: event_source_user_data.unwrap_or(crate::EVENT_MARKER as i64),
Expand Down Expand Up @@ -580,6 +590,7 @@ impl Enigo {
EventField::EVENT_SOURCE_USER_DATA,
self.event_source_user_data,
);
cg_event.set_flags(self.event_flags);
cg_event.post(CGEventTapLocation::HID);
} else {
return Err(InputError::Simulate(
Expand Down Expand Up @@ -609,6 +620,7 @@ impl Enigo {
EventField::EVENT_SOURCE_USER_DATA,
self.event_source_user_data,
);
cg_event.set_flags(self.event_flags);
cg_event.post(CGEventTapLocation::HID);
} else {
return Err(InputError::Simulate(
Expand All @@ -624,6 +636,56 @@ impl Enigo {
let ptr: *mut c_void = unsafe { msg_send![event, CGEvent] };
unsafe { CGEventRef::from_ptr(ptr.cast()) }
}

#[allow(clippy::match_same_arms)] // TODO: Remove this once the values for KeyCode were upstreamed: https://github.com/servo/core-foundation-rs/pull/712
fn add_event_flag(&mut self, keycode: CGKeyCode, direction: Direction) {
// CapsLock is special and gets toggled when pressed down
if keycode == KeyCode::CAPS_LOCK && direction != Direction::Release {
self.event_flags.toggle(CGEventFlags::CGEventFlagAlphaShift);
return;
}

let set = match direction {
Direction::Click => {
return;
}
Direction::Press => true,
Direction::Release => false,
};

let event_flag = match keycode {
// KeyCode::CAPS_LOCK => CGEventFlags::CGEventFlagAlphaShift, // Can never happen,
// because it is previously handled
KeyCode::SHIFT | KeyCode::RIGHT_SHIFT => CGEventFlags::CGEventFlagShift,
KeyCode::CONTROL | KeyCode::RIGHT_CONTROL => CGEventFlags::CGEventFlagControl,
KeyCode::OPTION | KeyCode::RIGHT_OPTION => CGEventFlags::CGEventFlagAlternate,
KeyCode::COMMAND | KeyCode::RIGHT_COMMAND => CGEventFlags::CGEventFlagCommand,
KeyCode::HELP => CGEventFlags::CGEventFlagHelp,
// KeyCode:: => CGEventFlags::CGEventFlagSecondaryFn, TODO: Check if a KeyCode exists
// that requires this flag to get set
83 => CGEventFlags::CGEventFlagNumericPad, // Numpad 1
84 => CGEventFlags::CGEventFlagNumericPad, // Numpad 2
85 => CGEventFlags::CGEventFlagNumericPad, // Numpad 3
86 => CGEventFlags::CGEventFlagNumericPad, // Numpad 4
87 => CGEventFlags::CGEventFlagNumericPad, // Numpad 5
88 => CGEventFlags::CGEventFlagNumericPad, // Numpad 6
89 => CGEventFlags::CGEventFlagNumericPad, // Numpad 7
91 => CGEventFlags::CGEventFlagNumericPad, // Numpad 8
92 => CGEventFlags::CGEventFlagNumericPad, // Numpad 9
82 => CGEventFlags::CGEventFlagNumericPad, // Numpad 0
67 => CGEventFlags::CGEventFlagNumericPad, // Numpad *
75 => CGEventFlags::CGEventFlagNumericPad, // Numpad /
69 => CGEventFlags::CGEventFlagNumericPad, // Numpad +
78 => CGEventFlags::CGEventFlagNumericPad, // Numpad -
81 => CGEventFlags::CGEventFlagNumericPad, // Numpad =
65 => CGEventFlags::CGEventFlagNumericPad, // Numpad .
71 => CGEventFlags::CGEventFlagNumericPad, // Numpad clear
76 => CGEventFlags::CGEventFlagNumericPad, // Numpad enter
95 => CGEventFlags::CGEventFlagNumericPad, // Numpad Comma/Separator (JIS layout)
_ => CGEventFlags::CGEventFlagNull,
};
self.event_flags.set(event_flag, set);
}
}

/// Converts a `Key` to a `CGKeyCode`
Expand Down

0 comments on commit 83202ea

Please sign in to comment.