From f72593c28116dd3c201ebcb8c598778dd3e2e488 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 8 Apr 2023 19:07:24 +0800 Subject: [PATCH 01/12] tmp commit Signed-off-by: fufesou --- libs/enigo/src/win/win_impl.rs | 6 +- src/keyboard.rs | 71 ++++++++++++++++++---- src/lib.rs | 2 +- src/server/input_service.rs | 105 ++++++++++++++++----------------- 4 files changed, 114 insertions(+), 70 deletions(-) diff --git a/libs/enigo/src/win/win_impl.rs b/libs/enigo/src/win/win_impl.rs index a2839621c..f183e94ae 100644 --- a/libs/enigo/src/win/win_impl.rs +++ b/libs/enigo/src/win/win_impl.rs @@ -359,9 +359,6 @@ impl Enigo { } fn key_to_keycode(&self, key: Key) -> u16 { - unsafe { - LAYOUT = std::ptr::null_mut(); - } // do not use the codes from crate winapi they're // wrongly typed with i32 instead of i16 use the // ones provided by win/keycodes.rs that are prefixed @@ -456,6 +453,9 @@ impl Enigo { } fn get_layoutdependent_keycode(&self, chr: char) -> u16 { + unsafe { + LAYOUT = std::ptr::null_mut(); + } // NOTE VkKeyScanW uses the current keyboard LAYOUT // to specify a LAYOUT use VkKeyScanExW and GetKeyboardLayout // or load one with LoadKeyboardLayoutW diff --git a/src/keyboard.rs b/src/keyboard.rs index 15629bb00..7fa00da80 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -364,26 +364,73 @@ pub fn is_modifier(key: &rdev::Key) -> bool { ) } +#[inline] +#[cfg(not(any(target_os = "android", target_os = "ios")))] +pub fn is_numpad_rdev_key(key: &rdev::Key) -> bool { + matches!( + key, + Key::Kp0 + | Key::Kp1 + | Key::Kp2 + | Key::Kp3 + | Key::Kp4 + | Key::Kp5 + | Key::Kp6 + | Key::Kp7 + | Key::Kp8 + | Key::Kp9 + | Key::KpMinus + | Key::KpMultiply + | Key::KpDivide + | Key::KpPlus + | Key::KpDecimal + ) +} + +#[inline] +#[cfg(not(any(target_os = "android", target_os = "ios")))] +pub fn is_letter_rdev_key(key: &rdev::Key) -> bool { + matches!( + key, + Key::KeyA + | Key::KeyB + | Key::KeyC + | Key::KeyD + | Key::KeyE + | Key::KeyF + | Key::KeyG + | Key::KeyH + | Key::KeyI + | Key::KeyJ + | Key::KeyK + | Key::KeyL + | Key::KeyM + | Key::KeyN + | Key::KeyO + | Key::KeyP + | Key::KeyQ + | Key::KeyR + | Key::KeyS + | Key::KeyT + | Key::KeyU + | Key::KeyV + | Key::KeyW + | Key::KeyX + | Key::KeyY + | Key::KeyZ + ) +} + #[inline] #[cfg(not(any(target_os = "android", target_os = "ios")))] fn is_numpad_key(event: &Event) -> bool { - matches!(event.event_type, EventType::KeyPress(key) | EventType::KeyRelease(key) if match key { - Key::Kp0 | Key::Kp1 | Key::Kp2 | Key::Kp3 | Key::Kp4 | Key::Kp5 | Key::Kp6 | Key::Kp7 | Key::Kp8 | - Key::Kp9 | Key::KpMinus | Key::KpMultiply | Key::KpDivide | Key::KpPlus | Key::KpDecimal => true, - _ => false - }) + matches!(event.event_type, EventType::KeyPress(key) | EventType::KeyRelease(key) if is_numpad_rdev_key(&key)) } #[inline] #[cfg(not(any(target_os = "android", target_os = "ios")))] fn is_letter_key(event: &Event) -> bool { - matches!(event.event_type, EventType::KeyPress(key) | EventType::KeyRelease(key) if match key { - Key::KeyA | Key::KeyB | Key::KeyC | Key::KeyD | Key::KeyE | Key::KeyF | Key::KeyG | Key::KeyH | - Key::KeyI | Key::KeyJ | Key::KeyK | Key::KeyL | Key::KeyM | Key::KeyN | Key::KeyO | Key::KeyP | - Key::KeyQ | Key::KeyR | Key::KeyS | Key::KeyT | Key::KeyU | Key::KeyV | Key::KeyW | Key::KeyX | - Key::KeyY | Key::KeyZ => true, - _ => false - }) + matches!(event.event_type, EventType::KeyPress(key) | EventType::KeyRelease(key) if is_letter_rdev_key(&key)) } #[cfg(not(any(target_os = "android", target_os = "ios")))] diff --git a/src/lib.rs b/src/lib.rs index 45b4c63f3..f8ee744a0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ pub mod platform; mod keyboard; #[cfg(not(any(target_os = "android", target_os = "ios")))] -pub use keyboard::keycode_to_rdev_key; +pub use keyboard::{keycode_to_rdev_key, is_numpad_rdev_key, is_letter_rdev_key}; #[cfg(not(any(target_os = "android", target_os = "ios")))] pub use platform::{get_cursor, get_cursor_data, get_cursor_pos, start_os_service}; #[cfg(not(any(target_os = "ios")))] diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 0be6f0d84..12b625f9d 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -8,13 +8,14 @@ use hbb_common::{config::COMPRESS_LEVEL, get_time, protobuf::EnumOrUnknown}; use rdev::{self, EventType, Key as RdevKey, KeyCode, RawKey}; #[cfg(target_os = "macos")] use rdev::{CGEventSourceStateID, CGEventTapLocation, VirtualInput}; -use std::time::Duration; +#[cfg(any(target_os = "windows", target_os = "linux"))] +use std::collections::HashSet; use std::{ convert::TryFrom, ops::Sub, sync::atomic::{AtomicBool, Ordering}, thread, - time::{self, Instant}, + time::{self, Duration, Instant}, }; #[cfg(target_os = "windows")] use winapi::um::winuser::{ @@ -153,7 +154,15 @@ impl LockModesHandler { #[cfg(not(target_os = "windows"))] let disable_numlock = false; #[cfg(target_os = "windows")] - let disable_numlock = is_numlock_disabled(key_event); + let disable_numlock = if key_event.mode == KeyboardMode::Legacy.into() { + // disable numlock if press home etc when numlock is on, + // because we will get numpad value (7,8,9 etc) if not + has_numpad_key(key_event) + } else { + false + }; + let disable_numlock = false; + println!("REMOVE ME ======================= event_num_enabled {}, local_num_enabled {}", event_num_enabled, local_num_enabled); let num_lock_changed = event_num_enabled != local_num_enabled && !disable_numlock; if num_lock_changed { en.key_click(enigo::Key::NumLock); @@ -1020,35 +1029,6 @@ fn has_numpad_key(key_event: &KeyEvent) -> bool { != 0 } -#[cfg(target_os = "windows")] -fn is_rdev_numpad_key(key_event: &KeyEvent) -> bool { - let code = key_event.chr(); - let key = rdev::get_win_key(code, 0); - match key { - RdevKey::Home - | RdevKey::UpArrow - | RdevKey::PageUp - | RdevKey::LeftArrow - | RdevKey::RightArrow - | RdevKey::End - | RdevKey::DownArrow - | RdevKey::PageDown - | RdevKey::Insert - | RdevKey::Delete => true, - _ => false, - } -} - -#[cfg(target_os = "windows")] -fn is_numlock_disabled(key_event: &KeyEvent) -> bool { - // disable numlock if press home etc when numlock is on, - // because we will get numpad value (7,8,9 etc) if not - match key_event.mode.unwrap() { - KeyboardMode::Map => is_rdev_numpad_key(key_event), - _ => has_numpad_key(key_event), - } -} - fn map_keyboard_mode(evt: &KeyEvent) { #[cfg(windows)] crate::platform::windows::try_change_desktop(); @@ -1383,15 +1363,29 @@ fn skip_led_sync_control_key(_evt: &KeyEvent) -> bool { // https://github.com/rustdesk/rustdesk/issues/3928#issuecomment-1500773473 #[cfg(any(target_os = "windows", target_os = "linux"))] fn skip_led_sync_control_key(key: &ControlKey) -> bool { - [ - ControlKey::Control, - ControlKey::Meta, - ControlKey::Shift, - ControlKey::Alt, - ControlKey::Tab, - ControlKey::Return, - ] - .contains(key) + matches!( + key, + ControlKey::Control + | ControlKey::RControl + | ControlKey::Meta + | ControlKey::Shift + | ControlKey::RShift + | ControlKey::Alt + | ControlKey::RAlt + | ControlKey::Tab + | ControlKey::Return + | ControlKey::Numpad0 + | ControlKey::Numpad1 + | ControlKey::Numpad2 + | ControlKey::Numpad3 + | ControlKey::Numpad4 + | ControlKey::Numpad5 + | ControlKey::Numpad6 + | ControlKey::Numpad7 + | ControlKey::Numpad8 + | ControlKey::Numpad9 + | ControlKey::NumpadEnter + ) } #[cfg(not(any(target_os = "windows", target_os = "linux")))] @@ -1401,19 +1395,20 @@ fn skip_led_sync_rdev_key(_evt: &KeyEvent) -> bool { #[cfg(any(target_os = "windows", target_os = "linux"))] fn skip_led_sync_rdev_key(key: &RdevKey) -> bool { - [ - RdevKey::ControlLeft, - RdevKey::ControlRight, - RdevKey::MetaLeft, - RdevKey::MetaRight, - RdevKey::ShiftRight, - RdevKey::ShiftRight, - RdevKey::Alt, - RdevKey::AltGr, - RdevKey::Tab, - RdevKey::Return, - ] - .contains(key) + crate::is_numpad_rdev_key(key) + || matches!( + key, + RdevKey::ControlLeft + | RdevKey::ControlRight + | RdevKey::MetaLeft + | RdevKey::MetaRight + | RdevKey::ShiftLeft + | RdevKey::ShiftRight + | RdevKey::Alt + | RdevKey::AltGr + | RdevKey::Tab + | RdevKey::Return + ) } pub fn handle_key_(evt: &KeyEvent) { @@ -1421,6 +1416,8 @@ pub fn handle_key_(evt: &KeyEvent) { return; } + println!("REMOVE ME ============================== {:?}", &evt); + let mut _lock_mode_handler = None; match (&evt.union, evt.mode.enum_value_or(KeyboardMode::Legacy)) { (Some(key_event::Union::Unicode(..)) | Some(key_event::Union::Seq(..)), _) => { From e2dbfb7f1b26f75f37f930b35382231c65904835 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 8 Apr 2023 19:48:27 +0800 Subject: [PATCH 02/12] refact keyboard handler Signed-off-by: fufesou --- src/server/input_service.rs | 72 +++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 12b625f9d..60c4ad8bc 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -140,7 +140,7 @@ impl LockModesHandler { } #[cfg(not(target_os = "macos"))] - fn new(key_event: &KeyEvent) -> Self { + fn new(key_event: &KeyEvent, is_numpad_key: bool) -> Self { let mut en = ENIGO.lock().unwrap(); let event_caps_enabled = Self::is_modifier_enabled(key_event, ControlKey::CapsLock); let local_caps_enabled = en.get_key_state(enigo::Key::CapsLock); @@ -154,16 +154,9 @@ impl LockModesHandler { #[cfg(not(target_os = "windows"))] let disable_numlock = false; #[cfg(target_os = "windows")] - let disable_numlock = if key_event.mode == KeyboardMode::Legacy.into() { - // disable numlock if press home etc when numlock is on, - // because we will get numpad value (7,8,9 etc) if not - has_numpad_key(key_event) - } else { - false - }; - let disable_numlock = false; - println!("REMOVE ME ======================= event_num_enabled {}, local_num_enabled {}", event_num_enabled, local_num_enabled); - let num_lock_changed = event_num_enabled != local_num_enabled && !disable_numlock; + let disable_numlock = is_numlock_disabled(key_event); + let num_lock_changed = + is_numpad_key && event_num_enabled != local_num_enabled && !disable_numlock; if num_lock_changed { en.key_click(enigo::Key::NumLock); } @@ -213,6 +206,18 @@ impl Drop for LockModesHandler { } } +#[inline] +#[cfg(target_os = "windows")] +fn is_numlock_disabled(key_event: &KeyEvent) -> bool { + // disable numlock if press home etc when numlock is on, + // because we will get numpad value (7,8,9 etc) if not + if key_event.mode.enum_value_or(KeyboardMode::Legacy) == KeyboardMode::Legacy { + has_numpad_key(key_event) + } else { + false + } +} + pub const NAME_CURSOR: &'static str = "mouse_cursor"; pub const NAME_POS: &'static str = "mouse_pos"; pub type MouseCursorService = ServiceTmpl; @@ -1374,7 +1379,14 @@ fn skip_led_sync_control_key(key: &ControlKey) -> bool { | ControlKey::RAlt | ControlKey::Tab | ControlKey::Return - | ControlKey::Numpad0 + ) +} + +#[inline] +fn is_numpad_control_key(key: &ControlKey) -> bool { + matches!( + key, + ControlKey::Numpad0 | ControlKey::Numpad1 | ControlKey::Numpad2 | ControlKey::Numpad3 @@ -1395,20 +1407,19 @@ fn skip_led_sync_rdev_key(_evt: &KeyEvent) -> bool { #[cfg(any(target_os = "windows", target_os = "linux"))] fn skip_led_sync_rdev_key(key: &RdevKey) -> bool { - crate::is_numpad_rdev_key(key) - || matches!( - key, - RdevKey::ControlLeft - | RdevKey::ControlRight - | RdevKey::MetaLeft - | RdevKey::MetaRight - | RdevKey::ShiftLeft - | RdevKey::ShiftRight - | RdevKey::Alt - | RdevKey::AltGr - | RdevKey::Tab - | RdevKey::Return - ) + matches!( + key, + RdevKey::ControlLeft + | RdevKey::ControlRight + | RdevKey::MetaLeft + | RdevKey::MetaRight + | RdevKey::ShiftLeft + | RdevKey::ShiftRight + | RdevKey::Alt + | RdevKey::AltGr + | RdevKey::Tab + | RdevKey::Return + ) } pub fn handle_key_(evt: &KeyEvent) { @@ -1416,23 +1427,22 @@ pub fn handle_key_(evt: &KeyEvent) { return; } - println!("REMOVE ME ============================== {:?}", &evt); - let mut _lock_mode_handler = None; match (&evt.union, evt.mode.enum_value_or(KeyboardMode::Legacy)) { (Some(key_event::Union::Unicode(..)) | Some(key_event::Union::Seq(..)), _) => { - _lock_mode_handler = Some(LockModesHandler::new(&evt)); + _lock_mode_handler = Some(LockModesHandler::new(&evt, false)); } (Some(key_event::Union::ControlKey(ck)), _) => { let key = ck.enum_value_or(ControlKey::Unknown); if !skip_led_sync_control_key(&key) { - _lock_mode_handler = Some(LockModesHandler::new(&evt)); + _lock_mode_handler = Some(LockModesHandler::new(&evt, is_numpad_control_key(&key))); } } (Some(key_event::Union::Chr(code)), KeyboardMode::Map | KeyboardMode::Translate) => { let key = crate::keycode_to_rdev_key(*code); if !skip_led_sync_rdev_key(&key) { - _lock_mode_handler = Some(LockModesHandler::new(evt)); + _lock_mode_handler = + Some(LockModesHandler::new(evt, crate::is_numpad_rdev_key(&key))); } } _ => {} From fa02246e1a548edc1c6941fd4596476184f13e8b Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 8 Apr 2023 20:14:43 +0800 Subject: [PATCH 03/12] fix build Signed-off-by: fufesou --- src/server/input_service.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 60c4ad8bc..6c307204d 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -124,13 +124,13 @@ impl Subscriber for MouseCursorSub { } } -#[cfg(not(target_os = "macos"))] +#[cfg(any(target_os = "windows", target_os = "linux"))] struct LockModesHandler { caps_lock_changed: bool, num_lock_changed: bool, } -#[cfg(target_os = "macos")] +#[cfg(not(any(target_os = "windows", target_os = "linux")))] struct LockModesHandler; impl LockModesHandler { @@ -139,7 +139,7 @@ impl LockModesHandler { key_event.modifiers.contains(&modifier.into()) } - #[cfg(not(target_os = "macos"))] + #[cfg(any(target_os = "windows", target_os = "linux"))] fn new(key_event: &KeyEvent, is_numpad_key: bool) -> Self { let mut en = ENIGO.lock().unwrap(); let event_caps_enabled = Self::is_modifier_enabled(key_event, ControlKey::CapsLock); @@ -167,8 +167,8 @@ impl LockModesHandler { } } - #[cfg(target_os = "macos")] - fn new(key_event: &KeyEvent) -> Self { + #[cfg(not(any(target_os = "windows", target_os = "linux")))] + fn new(key_event: &KeyEvent, _is_numpad_key: bool) -> Self { let event_caps_enabled = Self::is_modifier_enabled(key_event, ControlKey::CapsLock); // Do not use the following code to detect `local_caps_enabled`. // Because the state of get_key_state will not affect simuation of `VIRTUAL_INPUT_STATE` in this file. @@ -193,7 +193,7 @@ impl LockModesHandler { } } -#[cfg(not(target_os = "macos"))] +#[cfg(any(target_os = "windows", target_os = "linux"))] impl Drop for LockModesHandler { fn drop(&mut self) { let mut en = ENIGO.lock().unwrap(); @@ -1357,7 +1357,7 @@ fn simulate_win2win_hotkey(code: u32, down: bool) { } #[cfg(not(any(target_os = "windows", target_os = "linux")))] -fn skip_led_sync_control_key(_evt: &KeyEvent) -> bool { +fn skip_led_sync_control_key(_key: &ControlKey) -> bool { false } @@ -1401,7 +1401,7 @@ fn is_numpad_control_key(key: &ControlKey) -> bool { } #[cfg(not(any(target_os = "windows", target_os = "linux")))] -fn skip_led_sync_rdev_key(_evt: &KeyEvent) -> bool { +fn skip_led_sync_rdev_key(_key: &RdevKey) -> bool { false } @@ -1427,7 +1427,9 @@ pub fn handle_key_(evt: &KeyEvent) { return; } + #[cfg(not(any(target_os = "android", target_os = "ios")))] let mut _lock_mode_handler = None; + #[cfg(not(any(target_os = "android", target_os = "ios")))] match (&evt.union, evt.mode.enum_value_or(KeyboardMode::Legacy)) { (Some(key_event::Union::Unicode(..)) | Some(key_event::Union::Seq(..)), _) => { _lock_mode_handler = Some(LockModesHandler::new(&evt, false)); From d66ad5e0cb2c9fea9d71324d2bc9bf86ff230b36 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 8 Apr 2023 20:17:55 +0800 Subject: [PATCH 04/12] remove unused Signed-off-by: fufesou --- src/server/input_service.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 6c307204d..ea29f67b0 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -8,8 +8,6 @@ use hbb_common::{config::COMPRESS_LEVEL, get_time, protobuf::EnumOrUnknown}; use rdev::{self, EventType, Key as RdevKey, KeyCode, RawKey}; #[cfg(target_os = "macos")] use rdev::{CGEventSourceStateID, CGEventTapLocation, VirtualInput}; -#[cfg(any(target_os = "windows", target_os = "linux"))] -use std::collections::HashSet; use std::{ convert::TryFrom, ops::Sub, From 0d5d073a43df54f82384a2732d342cbb54ae0d22 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 8 Apr 2023 20:28:34 +0800 Subject: [PATCH 05/12] trivial changes Signed-off-by: fufesou --- src/keyboard.rs | 1 + src/lib.rs | 2 -- src/server/input_service.rs | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/keyboard.rs b/src/keyboard.rs index 7fa00da80..d683fd579 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -350,6 +350,7 @@ pub fn get_keyboard_mode_enum() -> KeyboardMode { } #[inline] +#[cfg(not(any(target_os = "android", target_os = "ios")))] pub fn is_modifier(key: &rdev::Key) -> bool { matches!( key, diff --git a/src/lib.rs b/src/lib.rs index f8ee744a0..5dcd6389c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,8 +3,6 @@ pub mod platform; mod keyboard; #[cfg(not(any(target_os = "android", target_os = "ios")))] -pub use keyboard::{keycode_to_rdev_key, is_numpad_rdev_key, is_letter_rdev_key}; -#[cfg(not(any(target_os = "android", target_os = "ios")))] pub use platform::{get_cursor, get_cursor_data, get_cursor_pos, start_os_service}; #[cfg(not(any(target_os = "ios")))] /// cbindgen:ignore diff --git a/src/server/input_service.rs b/src/server/input_service.rs index ea29f67b0..a3f62b20e 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -1439,10 +1439,10 @@ pub fn handle_key_(evt: &KeyEvent) { } } (Some(key_event::Union::Chr(code)), KeyboardMode::Map | KeyboardMode::Translate) => { - let key = crate::keycode_to_rdev_key(*code); + let key = crate::keyboard::keycode_to_rdev_key(*code); if !skip_led_sync_rdev_key(&key) { _lock_mode_handler = - Some(LockModesHandler::new(evt, crate::is_numpad_rdev_key(&key))); + Some(LockModesHandler::new(evt, crate::keyboard::is_numpad_rdev_key(&key))); } } _ => {} From 20734f278ee07c1708ee4f2dc22f80e00d074ba5 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 8 Apr 2023 21:24:29 +0800 Subject: [PATCH 06/12] remove unused call Signed-off-by: fufesou --- src/server/input_service.rs | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/server/input_service.rs b/src/server/input_service.rs index a3f62b20e..e64baad70 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -128,7 +128,7 @@ struct LockModesHandler { num_lock_changed: bool, } -#[cfg(not(any(target_os = "windows", target_os = "linux")))] +#[cfg(target_os = "macos")] struct LockModesHandler; impl LockModesHandler { @@ -137,6 +137,19 @@ impl LockModesHandler { key_event.modifiers.contains(&modifier.into()) } + #[inline] + #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + fn new_handler(key_event: &KeyEvent, _is_numpad_key: bool) -> Self { + #[cfg(any(target_os = "windows", target_os = "linux"))] + { + Self::new(key_event, _is_numpad_key) + } + #[cfg(target_os = "macos")] + { + Self::new(key_event) + } + } + #[cfg(any(target_os = "windows", target_os = "linux"))] fn new(key_event: &KeyEvent, is_numpad_key: bool) -> Self { let mut en = ENIGO.lock().unwrap(); @@ -165,8 +178,8 @@ impl LockModesHandler { } } - #[cfg(not(any(target_os = "windows", target_os = "linux")))] - fn new(key_event: &KeyEvent, _is_numpad_key: bool) -> Self { + #[cfg(target_os = "macos")] + fn new(key_event: &KeyEvent) -> Self { let event_caps_enabled = Self::is_modifier_enabled(key_event, ControlKey::CapsLock); // Do not use the following code to detect `local_caps_enabled`. // Because the state of get_key_state will not affect simuation of `VIRTUAL_INPUT_STATE` in this file. @@ -1430,19 +1443,26 @@ pub fn handle_key_(evt: &KeyEvent) { #[cfg(not(any(target_os = "android", target_os = "ios")))] match (&evt.union, evt.mode.enum_value_or(KeyboardMode::Legacy)) { (Some(key_event::Union::Unicode(..)) | Some(key_event::Union::Seq(..)), _) => { - _lock_mode_handler = Some(LockModesHandler::new(&evt, false)); + _lock_mode_handler = Some(LockModesHandler::new_handler(&evt, false)); } (Some(key_event::Union::ControlKey(ck)), _) => { let key = ck.enum_value_or(ControlKey::Unknown); if !skip_led_sync_control_key(&key) { - _lock_mode_handler = Some(LockModesHandler::new(&evt, is_numpad_control_key(&key))); + #[cfg(target_os = "macos")] + let is_numpad_key = false; + #[cfg(any(target_os = "windows", target_os = "linux"))] + let is_numpad_key = is_numpad_control_key(&key); + _lock_mode_handler = Some(LockModesHandler::new_handler(&evt, is_numpad_key)); } } (Some(key_event::Union::Chr(code)), KeyboardMode::Map | KeyboardMode::Translate) => { let key = crate::keyboard::keycode_to_rdev_key(*code); if !skip_led_sync_rdev_key(&key) { - _lock_mode_handler = - Some(LockModesHandler::new(evt, crate::keyboard::is_numpad_rdev_key(&key))); + #[cfg(target_os = "macos")] + let is_numpad_key = false; + #[cfg(any(target_os = "windows", target_os = "linux"))] + let is_numpad_key = crate::keyboard::is_numpad_rdev_key(&key); + _lock_mode_handler = Some(LockModesHandler::new_handler(evt, is_numpad_key)); } } _ => {} From cee06f04252d4e0545a394dc9386b016c56a62c3 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 8 Apr 2023 21:26:19 +0800 Subject: [PATCH 07/12] remove warn Signed-off-by: fufesou --- src/server/input_service.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/input_service.rs b/src/server/input_service.rs index e64baad70..431a54362 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -1394,6 +1394,7 @@ fn skip_led_sync_control_key(key: &ControlKey) -> bool { } #[inline] +#[cfg(any(target_os = "windows", target_os = "linux"))] fn is_numpad_control_key(key: &ControlKey) -> bool { matches!( key, From 09ba9cddcd520d23b5fe1facd210bacdf67be057 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 8 Apr 2023 22:06:24 +0800 Subject: [PATCH 08/12] debug, win, legacy mode, led sync Signed-off-by: fufesou --- src/server/input_service.rs | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 431a54362..d60574852 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -222,7 +222,7 @@ impl Drop for LockModesHandler { fn is_numlock_disabled(key_event: &KeyEvent) -> bool { // disable numlock if press home etc when numlock is on, // because we will get numpad value (7,8,9 etc) if not - if key_event.mode.enum_value_or(KeyboardMode::Legacy) == KeyboardMode::Legacy { + if is_legacy_mode(&key_event) { has_numpad_key(key_event) } else { false @@ -1434,6 +1434,12 @@ fn skip_led_sync_rdev_key(key: &RdevKey) -> bool { ) } +#[inline] +#[cfg(not(any(target_os = "android", target_os = "ios")))] +fn is_legacy_mode(evt: &KeyEvent) -> bool { + evt.mode.enum_value_or(KeyboardMode::Legacy) == KeyboardMode::Legacy +} + pub fn handle_key_(evt: &KeyEvent) { if EXITING.load(Ordering::SeqCst) { return; @@ -1442,11 +1448,11 @@ pub fn handle_key_(evt: &KeyEvent) { #[cfg(not(any(target_os = "android", target_os = "ios")))] let mut _lock_mode_handler = None; #[cfg(not(any(target_os = "android", target_os = "ios")))] - match (&evt.union, evt.mode.enum_value_or(KeyboardMode::Legacy)) { - (Some(key_event::Union::Unicode(..)) | Some(key_event::Union::Seq(..)), _) => { + match &evt.union { + Some(key_event::Union::Unicode(..)) | Some(key_event::Union::Seq(..)) => { _lock_mode_handler = Some(LockModesHandler::new_handler(&evt, false)); } - (Some(key_event::Union::ControlKey(ck)), _) => { + Some(key_event::Union::ControlKey(ck)) => { let key = ck.enum_value_or(ControlKey::Unknown); if !skip_led_sync_control_key(&key) { #[cfg(target_os = "macos")] @@ -1456,14 +1462,18 @@ pub fn handle_key_(evt: &KeyEvent) { _lock_mode_handler = Some(LockModesHandler::new_handler(&evt, is_numpad_key)); } } - (Some(key_event::Union::Chr(code)), KeyboardMode::Map | KeyboardMode::Translate) => { - let key = crate::keyboard::keycode_to_rdev_key(*code); - if !skip_led_sync_rdev_key(&key) { - #[cfg(target_os = "macos")] - let is_numpad_key = false; - #[cfg(any(target_os = "windows", target_os = "linux"))] - let is_numpad_key = crate::keyboard::is_numpad_rdev_key(&key); - _lock_mode_handler = Some(LockModesHandler::new_handler(evt, is_numpad_key)); + Some(key_event::Union::Chr(code)) => { + if is_legacy_mode(&evt) { + _lock_mode_handler = Some(LockModesHandler::new_handler(evt, false)); + } else { + let key = crate::keyboard::keycode_to_rdev_key(*code); + if !skip_led_sync_rdev_key(&key) { + #[cfg(target_os = "macos")] + let is_numpad_key = false; + #[cfg(any(target_os = "windows", target_os = "linux"))] + let is_numpad_key = crate::keyboard::is_numpad_rdev_key(&key); + _lock_mode_handler = Some(LockModesHandler::new_handler(evt, is_numpad_key)); + } } } _ => {} From 09f9b515f6b84b48f618c949cd8bbb623269ff67 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 8 Apr 2023 22:54:36 +0800 Subject: [PATCH 09/12] remove unused call Signed-off-by: fufesou --- src/server/input_service.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/server/input_service.rs b/src/server/input_service.rs index d60574852..ddd7a0149 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -160,14 +160,16 @@ impl LockModesHandler { en.key_click(enigo::Key::CapsLock); } - let event_num_enabled = Self::is_modifier_enabled(key_event, ControlKey::NumLock); - let local_num_enabled = en.get_key_state(enigo::Key::NumLock); - #[cfg(not(target_os = "windows"))] - let disable_numlock = false; - #[cfg(target_os = "windows")] - let disable_numlock = is_numlock_disabled(key_event); - let num_lock_changed = - is_numpad_key && event_num_enabled != local_num_enabled && !disable_numlock; + let mut num_lock_changed = false; + if is_numpad_key { + let event_num_enabled = Self::is_modifier_enabled(key_event, ControlKey::NumLock); + let local_num_enabled = en.get_key_state(enigo::Key::NumLock); + #[cfg(not(target_os = "windows"))] + let disable_numlock = false; + #[cfg(target_os = "windows")] + let disable_numlock = is_numlock_disabled(key_event); + num_lock_changed = event_num_enabled != local_num_enabled && !disable_numlock; + } if num_lock_changed { en.key_click(enigo::Key::NumLock); } From 579b21066fad175646b57aa3542a8346800c9d91 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sun, 9 Apr 2023 00:06:17 +0800 Subject: [PATCH 10/12] fix, win, legacy mode, shift + home Signed-off-by: fufesou --- src/server/input_service.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/input_service.rs b/src/server/input_service.rs index ddd7a0149..788c1ed62 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -161,7 +161,7 @@ impl LockModesHandler { } let mut num_lock_changed = false; - if is_numpad_key { + if is_numpad_key || is_legacy_mode(key_event) { let event_num_enabled = Self::is_modifier_enabled(key_event, ControlKey::NumLock); let local_num_enabled = en.get_key_state(enigo::Key::NumLock); #[cfg(not(target_os = "windows"))] From 241cb1d24ee5a4919dc72dff4157c9fea0494a2c Mon Sep 17 00:00:00 2001 From: fufesou Date: Sun, 9 Apr 2023 00:36:59 +0800 Subject: [PATCH 11/12] trivial changes Signed-off-by: fufesou --- src/server/input_service.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 788c1ed62..2b1f16886 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -161,7 +161,7 @@ impl LockModesHandler { } let mut num_lock_changed = false; - if is_numpad_key || is_legacy_mode(key_event) { + if is_numpad_key { let event_num_enabled = Self::is_modifier_enabled(key_event, ControlKey::NumLock); let local_num_enabled = en.get_key_state(enigo::Key::NumLock); #[cfg(not(target_os = "windows"))] @@ -1461,7 +1461,12 @@ pub fn handle_key_(evt: &KeyEvent) { let is_numpad_key = false; #[cfg(any(target_os = "windows", target_os = "linux"))] let is_numpad_key = is_numpad_control_key(&key); - _lock_mode_handler = Some(LockModesHandler::new_handler(&evt, is_numpad_key)); + // Legacy mode need to disable numlock if home/end/arraws/page down/page up + // are pressed. + _lock_mode_handler = Some(LockModesHandler::new_handler( + &evt, + is_numpad_key || is_legacy_mode(evt), + )); } } Some(key_event::Union::Chr(code)) => { From 2ce1df1ad4f4ca7e8f4213da6ad837d69092f124 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sun, 9 Apr 2023 12:14:01 +0800 Subject: [PATCH 12/12] fix, legacy mode, numlock Signed-off-by: fufesou --- src/server/input_service.rs | 41 ++++++++++++++----------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 2b1f16886..ab5f7e287 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -162,13 +162,15 @@ impl LockModesHandler { let mut num_lock_changed = false; if is_numpad_key { - let event_num_enabled = Self::is_modifier_enabled(key_event, ControlKey::NumLock); let local_num_enabled = en.get_key_state(enigo::Key::NumLock); - #[cfg(not(target_os = "windows"))] - let disable_numlock = false; + let event_num_enabled = Self::is_modifier_enabled(key_event, ControlKey::NumLock); + num_lock_changed = event_num_enabled != local_num_enabled; + } else if is_legacy_mode(key_event) { #[cfg(target_os = "windows")] - let disable_numlock = is_numlock_disabled(key_event); - num_lock_changed = event_num_enabled != local_num_enabled && !disable_numlock; + { + num_lock_changed = + should_disable_numlock(key_event) && en.get_key_state(enigo::Key::NumLock); + } } if num_lock_changed { en.key_click(enigo::Key::NumLock); @@ -221,14 +223,16 @@ impl Drop for LockModesHandler { #[inline] #[cfg(target_os = "windows")] -fn is_numlock_disabled(key_event: &KeyEvent) -> bool { +fn should_disable_numlock(evt: &KeyEvent) -> bool { // disable numlock if press home etc when numlock is on, // because we will get numpad value (7,8,9 etc) if not - if is_legacy_mode(&key_event) { - has_numpad_key(key_event) - } else { - false + match (&evt.union, evt.mode.enum_value_or(KeyboardMode::Legacy)) { + (Some(key_event::Union::ControlKey(ck)), KeyboardMode::Legacy) => { + return NUMPAD_KEY_MAP.contains_key(&ck.value()); + } + _ => {} } + false } pub const NAME_CURSOR: &'static str = "mouse_cursor"; @@ -1037,16 +1041,6 @@ fn char_value_to_key(value: u32) -> Key { Key::Layout(std::char::from_u32(value).unwrap_or('\0')) } -#[cfg(target_os = "windows")] -fn has_numpad_key(key_event: &KeyEvent) -> bool { - key_event - .modifiers - .iter() - .filter(|&&ck| NUMPAD_KEY_MAP.get(&ck.value()).is_some()) - .count() - != 0 -} - fn map_keyboard_mode(evt: &KeyEvent) { #[cfg(windows)] crate::platform::windows::try_change_desktop(); @@ -1461,12 +1455,7 @@ pub fn handle_key_(evt: &KeyEvent) { let is_numpad_key = false; #[cfg(any(target_os = "windows", target_os = "linux"))] let is_numpad_key = is_numpad_control_key(&key); - // Legacy mode need to disable numlock if home/end/arraws/page down/page up - // are pressed. - _lock_mode_handler = Some(LockModesHandler::new_handler( - &evt, - is_numpad_key || is_legacy_mode(evt), - )); + _lock_mode_handler = Some(LockModesHandler::new_handler(&evt, is_numpad_key)); } } Some(key_event::Union::Chr(code)) => {