From 6144a1c97e6f858c9d9b051f8accebfa2948ec72 Mon Sep 17 00:00:00 2001 From: fufesou <13586388+fufesou@users.noreply.github.com> Date: Mon, 19 May 2025 21:02:07 +0800 Subject: [PATCH] fix: osx, reset modifiers' state after locking screen (#11806) https://github.com/rustdesk/rustdesk/issues/11802 Signed-off-by: fufesou --- libs/enigo/src/macos/macos_impl.rs | 45 ++++++++++++++++++++---------- src/server/input_service.rs | 2 +- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/libs/enigo/src/macos/macos_impl.rs b/libs/enigo/src/macos/macos_impl.rs index 92e202ef9..d85f3576f 100644 --- a/libs/enigo/src/macos/macos_impl.rs +++ b/libs/enigo/src/macos/macos_impl.rs @@ -141,9 +141,27 @@ impl Enigo { self.flags |= flag; } - fn post(&self, event: CGEvent) { - // event.set_flags(CGEventFlags::CGEventFlagNull); will cause `F11` not working. no idea why. - if !self.ignore_flags && self.flags != CGEventFlags::CGEventFlagNull { + // Just check F11 for minimal changes. + // Since enigo (legacy mode) is deprecated, it is currently in maintenance only. + fn post(&self, event: CGEvent, keycode: Option) { + if keycode == Some(kVK_F11) { + // Some key events require the flags to work. + // We can't simply set the flag to `CGEventFlags::CGEventFlagNull`. + // eg. `F11` requires flags `CGEventFlags::CGEventFlagSecondaryFn | 0x20000000` to work. + self.post_event(event, false); + } else { + // macOS system may use the previous event flag to generate the next event. + // Only found this issue when locking the screen. + // When we use enigo to lock the screen, the next mouse event will have the flag + // `CGEventFlagControl | CGEventFlagCommand | 0x20000000`. + // The key event will also have the flag `CGEventFlagControl | CGEventFlagCommand | 0x20000000`. + // Therefore, we need to set the flag to `event.set_flags(self.flags)` to avoid this. + self.post_event(event, true); + } + } + + fn post_event(&self, event: CGEvent, force_flags: bool) { + if !self.ignore_flags && (force_flags || self.flags != CGEventFlags::CGEventFlagNull) { event.set_flags(self.flags); } event.set_integer_value_field(EventField::EVENT_SOURCE_USER_DATA, ENIGO_INPUT_EXTRA_VALUE); @@ -205,7 +223,7 @@ impl MouseControllable for Enigo { if let Ok(event) = CGEvent::new_mouse_event(src.clone(), event_type, dest, CGMouseButton::Left) { - self.post(event); + self.post(event, None); } } } @@ -270,7 +288,7 @@ impl MouseControllable for Enigo { if let Some(v) = btn_value { event.set_integer_value_field(EventField::MOUSE_EVENT_BUTTON_NUMBER, v); } - self.post(event); + self.post(event, None); } } Ok(()) @@ -309,7 +327,7 @@ impl MouseControllable for Enigo { if let Some(v) = btn_value { event.set_integer_value_field(EventField::MOUSE_EVENT_BUTTON_NUMBER, v); } - self.post(event); + self.post(event, None); } } } @@ -395,7 +413,7 @@ impl KeyboardControllable for Enigo { if let Some(src) = self.event_source.as_ref() { if let Ok(event) = CGEvent::new_keyboard_event(src.clone(), 0, true) { event.set_string(cluster); - self.post(event); + self.post(event, None); } } } @@ -409,11 +427,11 @@ impl KeyboardControllable for Enigo { if let Some(src) = self.event_source.as_ref() { if let Ok(event) = CGEvent::new_keyboard_event(src.clone(), keycode, true) { - self.post(event); + self.post(event, Some(keycode)); } if let Ok(event) = CGEvent::new_keyboard_event(src.clone(), keycode, false) { - self.post(event); + self.post(event, Some(keycode)); } } } @@ -425,18 +443,17 @@ impl KeyboardControllable for Enigo { } if let Some(src) = self.event_source.as_ref() { if let Ok(event) = CGEvent::new_keyboard_event(src.clone(), code, true) { - self.post(event); + self.post(event, Some(code)); } } Ok(()) } fn key_up(&mut self, key: Key) { + let code = self.key_to_keycode(key); if let Some(src) = self.event_source.as_ref() { - if let Ok(event) = - CGEvent::new_keyboard_event(src.clone(), self.key_to_keycode(key), false) - { - self.post(event); + if let Ok(event) = CGEvent::new_keyboard_event(src.clone(), code, false) { + self.post(event, Some(code)); } } } diff --git a/src/server/input_service.rs b/src/server/input_service.rs index c0bb5ac6f..1b0a248d4 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -1205,7 +1205,7 @@ pub fn handle_key(evt: &KeyEvent) { // If we don't sleep, the key press/release events may not take effect. // // For example, the controlled side osx `12.7.6` or `15.1.1` - // If we input characters quickly and continuously, and press or release "Shift" for a short period of time, + // If we input characters quickly and continuously, and press or release "Shift" for a short period of time, // it is possible that after releasing "Shift", the controlled side will still print uppercase characters. // Though it is not very easy to reproduce. key_sleep();