diff --git a/libs/enigo/src/lib.rs b/libs/enigo/src/lib.rs index bf289c8ed..e5a19750c 100644 --- a/libs/enigo/src/lib.rs +++ b/libs/enigo/src/lib.rs @@ -347,7 +347,7 @@ pub enum Key { /// Clear, /// - Menu, + Menu, // deprecated, use alt instead /// Pause, /// @@ -409,6 +409,12 @@ pub enum Key { /// NumpadEnter, /// + RightShift, + /// + RightControl, + /// + RightAlt, + /// /// Function, /// mac /// keyboard layout dependent key Layout(char), @@ -485,7 +491,7 @@ impl Enigo { /// ``` pub fn new() -> Self { #[cfg(any(target_os = "android", target_os = "ios"))] - return Enigo{}; + return Enigo {}; #[cfg(not(any(target_os = "android", target_os = "ios")))] Self::default() } diff --git a/libs/enigo/src/linux.rs b/libs/enigo/src/linux.rs index 0e8078b10..58f134a18 100644 --- a/libs/enigo/src/linux.rs +++ b/libs/enigo/src/linux.rs @@ -260,7 +260,7 @@ fn keysequence<'a>(key: Key) -> Cow<'a, str> { Key::Mute => "", Key::Scroll => "Scroll_Lock", Key::NumLock => "Num_Lock", - Key::RWin => "", + Key::RWin => "Super_R", Key::Apps => "", Key::Multiply => "KP_Multiply", Key::Add => "KP_Add", @@ -268,6 +268,9 @@ fn keysequence<'a>(key: Key) -> Cow<'a, str> { Key::Divide => "KP_Divide", Key::Equals => "KP_Equal", Key::NumpadEnter => "KP_Enter", + Key::RightShift => "Shift_R", + Key::RightControl => "Control_R", + Key::RightAlt => "Alt_R", Key::Command | Key::Super | Key::Windows | Key::Meta => "Super", diff --git a/libs/enigo/src/macos/keycodes.rs b/libs/enigo/src/macos/keycodes.rs index e946789b1..8dcd2191b 100644 --- a/libs/enigo/src/macos/keycodes.rs +++ b/libs/enigo/src/macos/keycodes.rs @@ -70,3 +70,4 @@ pub const kVK_ANSI_KeypadDivide: u16 = 0x4B; pub const kVK_ANSI_KeypadEnter: u16 = 0x4C; pub const kVK_ANSI_KeypadMinus: u16 = 0x4E; pub const kVK_ANSI_KeypadEquals: u16 = 0x51; +pub const kVK_RIGHT_COMMAND: u16 = 0x36; diff --git a/libs/enigo/src/macos/macos_impl.rs b/libs/enigo/src/macos/macos_impl.rs index 746526dcd..bb4875c08 100644 --- a/libs/enigo/src/macos/macos_impl.rs +++ b/libs/enigo/src/macos/macos_impl.rs @@ -142,6 +142,8 @@ pub const kCFStringEncodingUTF8: u32 = 134_217_984; #[link(name = "Carbon", kind = "framework")] extern "C" { fn TISCopyCurrentKeyboardInputSource() -> TISInputSourceRef; + fn TISCopyCurrentKeyboardLayoutInputSource() -> TISInputSourceRef; + fn TISCopyCurrentASCIICapableKeyboardLayoutInputSource() -> TISInputSourceRef; // extern void * // TISGetInputSourceProperty( @@ -583,6 +585,10 @@ impl Enigo { Key::Subtract => kVK_ANSI_KeypadMinus, Key::Equals => kVK_ANSI_KeypadEquals, Key::NumLock => kVK_ANSI_KeypadClear, + Key::RWin => kVK_RIGHT_COMMAND, + Key::RightShift => kVK_RightShift, + Key::RightControl => kVK_RightControl, + Key::RightAlt => kVK_RightOption, Key::Raw(raw_keycode) => raw_keycode, Key::Layout(c) => self.get_layoutdependent_keycode(c.to_string()), @@ -600,6 +606,7 @@ impl Enigo { } fn init_map(&mut self) { + println!("init_map"); self.keycode_to_string_map.insert("".to_owned(), 0); // loop through every keycode (0 - 127) for keycode in 0..128 { @@ -649,14 +656,44 @@ impl Enigo { fn create_string_for_key(&self, keycode: u16, modifier: u32) -> CFStringRef { let current_keyboard = unsafe { TISCopyCurrentKeyboardInputSource() }; - let layout_data = unsafe { - TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) - }; + let mut layout_data = std::ptr::null_mut(); + if !current_keyboard.is_null() { + layout_data = unsafe { + TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) + }; + } + if layout_data.is_null() { + // https://github.com/microsoft/vscode/issues/23833 + let current_keyboard = unsafe { TISCopyCurrentKeyboardLayoutInputSource() }; + if !current_keyboard.is_null() { + layout_data = unsafe { + TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) + }; + } + } + if layout_data.is_null() { + let current_keyboard = unsafe { TISCopyCurrentASCIICapableKeyboardLayoutInputSource() }; + if !current_keyboard.is_null() { + layout_data = unsafe { + TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) + }; + } + } + if layout_data.is_null() { + // to-do: try out manual mapping in https://github.com/stweil/OSXvnc + // we do see crash like this, also not easy to reproduce, no sure if it related +/* +0 rustdesk 0x000000010f921bc9 std::collections::hash::map::HashMap$LT$K$C$V$C$S$GT$::insert::h84e28c51a3292e7a + 473 +1 rustdesk 0x000000010f921884 enigo::macos::macos_impl::Enigo::key_to_keycode::h85ead82e9b1075ae + 1428 +2 rustdesk 0x000000010f922a8c _$LT$enigo..macos..macos_impl..Enigo$u20$as$u20$enigo..KeyboardControllable$GT$::key_down::h54f24da6d274b948 + 44 +*/ + return std::ptr::null() as _; + } let keyboard_layout = unsafe { CFDataGetBytePtr(layout_data) }; let mut keys_down: UInt32 = 0; - // let mut chars: *mut c_void;//[UniChar; 4]; let mut chars: u16 = 0; + // let mut chars: *mut c_void;//[UniChar; 4]; let mut real_length: UniCharCount = 0; unsafe { UCKeyTranslate( diff --git a/libs/enigo/src/win/keycodes.rs b/libs/enigo/src/win/keycodes.rs index 2dc99275a..58122cb83 100644 --- a/libs/enigo/src/win/keycodes.rs +++ b/libs/enigo/src/win/keycodes.rs @@ -7,9 +7,14 @@ pub const EVK_BACK: u16 = 0x08; pub const EVK_ESCAPE: u16 = 0x1b; pub const EVK_LWIN: u16 = 0x5b; pub const EVK_SHIFT: u16 = 0x10; +//pub const EVK_LSHIFT: u16 = 0xa0; +pub const EVK_RSHIFT: u16 = 0xa1; +//pub const EVK_LMENU: u16 = 0xa4; +pub const EVK_RMENU: u16 = 0xa5; pub const EVK_CAPITAL: u16 = 0x14; pub const EVK_MENU: u16 = 0x12; pub const EVK_LCONTROL: u16 = 0xa2; +pub const EVK_RCONTROL: u16 = 0xa3; pub const EVK_HOME: u16 = 0x24; pub const EVK_PRIOR: u16 = 0x21; pub const EVK_NEXT: u16 = 0x22; diff --git a/libs/enigo/src/win/win_impl.rs b/libs/enigo/src/win/win_impl.rs index df636e978..73917cde4 100644 --- a/libs/enigo/src/win/win_impl.rs +++ b/libs/enigo/src/win/win_impl.rs @@ -338,10 +338,14 @@ impl Enigo { Key::Divide => EVK_DIVIDE, Key::NumpadEnter => EVK_RETURN, Key::Equals => '=' as _, + Key::RightShift => EVK_RSHIFT, + Key::RightControl => EVK_RCONTROL, + Key::RightAlt => EVK_RMENU, Key::Raw(raw_keycode) => raw_keycode, Key::Layout(c) => self.get_layoutdependent_keycode(c.to_string()), Key::Super | Key::Command | Key::Windows | Key::Meta => EVK_LWIN, + _ => 0, } } diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index 6a2a03299..a8e8d34b5 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -129,7 +129,7 @@ enum ControlKey { Numpad9 = 42; Cancel = 43; Clear = 44; - Menu = 45; + Menu = 45; // deprecated, use Alt instead Pause = 46; Kana = 47; Hangul = 48; @@ -157,6 +157,9 @@ enum ControlKey { Divide = 70; Equals = 71; NumpadEnter = 72; + RShift= 73; + RControl = 74; + RAlt = 75; CtrlAltDel = 100; LockScreen = 101; } diff --git a/src/client.rs b/src/client.rs index d2fea14c3..2fd6e1430 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1068,7 +1068,7 @@ lazy_static::lazy_static! { ("VK_RETURN", Key::ControlKey(ControlKey::Return)), ("VK_SHIFT", Key::ControlKey(ControlKey::Shift)), ("VK_CONTROL", Key::ControlKey(ControlKey::Control)), - ("VK_MENU", Key::ControlKey(ControlKey::Menu)), + ("VK_MENU", Key::ControlKey(ControlKey::Alt)), ("VK_PAUSE", Key::ControlKey(ControlKey::Pause)), ("VK_CAPITAL", Key::ControlKey(ControlKey::CapsLock)), ("VK_KANA", Key::ControlKey(ControlKey::Kana)), @@ -1107,6 +1107,10 @@ lazy_static::lazy_static! { ("VK_NUMPAD7", Key::ControlKey(ControlKey::Numpad7)), ("VK_NUMPAD8", Key::ControlKey(ControlKey::Numpad8)), ("VK_NUMPAD9", Key::ControlKey(ControlKey::Numpad9)), + ("RAlt", Key::ControlKey(ControlKey::RAlt)), + ("RWin", Key::ControlKey(ControlKey::RWin)), + ("RControl", Key::ControlKey(ControlKey::RControl)), + ("RShift", Key::ControlKey(ControlKey::RShift)), ("CTRL_ALT_DEL", Key::ControlKey(ControlKey::CtrlAltDel)), ("LOCK_SCREEN", Key::ControlKey(ControlKey::LockScreen)), ].iter().cloned().collect(); diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 363164ee8..957a01653 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -174,7 +174,6 @@ pub fn is_left_up(evt: &MouseEvent) -> bool { #[cfg(windows)] pub fn mouse_move_relative(x: i32, y: i32) { - #[cfg(windows)] crate::platform::windows::try_change_desktop(); let mut en = ENIGO.lock().unwrap(); en.mouse_move_relative(x, y); @@ -340,7 +339,7 @@ lazy_static::lazy_static! { (ControlKey::Numpad9, enigo::Key::Numpad9), (ControlKey::Cancel, enigo::Key::Cancel), (ControlKey::Clear, enigo::Key::Clear), - (ControlKey::Menu, enigo::Key::Menu), + (ControlKey::Menu, enigo::Key::Alt), (ControlKey::Pause, enigo::Key::Pause), (ControlKey::Kana, enigo::Key::Kana), (ControlKey::Hangul, enigo::Key::Hangul), @@ -368,6 +367,10 @@ lazy_static::lazy_static! { (ControlKey::Divide, enigo::Key::Divide), (ControlKey::Equals, enigo::Key::Equals), (ControlKey::NumpadEnter, enigo::Key::NumpadEnter), + (ControlKey::RAlt, enigo::Key::RightAlt), + (ControlKey::RWin, enigo::Key::RWin), + (ControlKey::RControl, enigo::Key::RightControl), + (ControlKey::RShift, enigo::Key::RightShift), ].iter().map(|(a, b)| (a.value(), b.clone())).collect(); static ref NUMPAD_KEY_MAP: HashMap = [ diff --git a/src/ui/remote.rs b/src/ui/remote.rs index 359f11a4f..0af34704d 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -711,6 +711,7 @@ impl Handler { 0x4C => key_event.set_control_key(ControlKey::NumpadEnter), // numpad enter 0x69 => key_event.set_control_key(ControlKey::Snapshot), 0x72 => key_event.set_control_key(ControlKey::Help), + 0x6E => key_event.set_control_key(ControlKey::Apps), 0x47 => { key_event.set_control_key(if self.peer_platform() == "Mac OS" { ControlKey::Clear @@ -732,6 +733,7 @@ impl Handler { 0x91 => key_event.set_control_key(ControlKey::Scroll), 0x90 => key_event.set_control_key(ControlKey::NumLock), 0x5C => key_event.set_control_key(ControlKey::RWin), + 0x5B => key_event.set_control_key(ControlKey::Meta), 0x5D => key_event.set_control_key(ControlKey::Apps), 0xBE => key_event.set_chr('.' as _), 0xC0 => key_event.set_chr('`' as _), @@ -740,6 +742,44 @@ impl Handler { return None; } } + } else if cfg!(target_os = "linux") { + match code { + 65300 => key_event.set_control_key(ControlKey::Scroll), + 65421 => key_event.set_control_key(ControlKey::NumpadEnter), // numpad enter + 65407 => key_event.set_control_key(ControlKey::NumLock), + 65516 => key_event.set_control_key(ControlKey::RWin), + 65513 => key_event.set_control_key(ControlKey::Alt), + 65514 => key_event.set_control_key(ControlKey::RAlt), + 65508 => key_event.set_control_key(ControlKey::RControl), + 65506 => key_event.set_control_key(ControlKey::RShift), + 96 => key_event.set_chr('`' as _), + 46 => key_event.set_chr('.' as _), + 126 => key_event.set_chr('`' as _), + 33 => key_event.set_chr('1' as _), + 64 => key_event.set_chr('2' as _), + 35 => key_event.set_chr('3' as _), + 36 => key_event.set_chr('4' as _), + 37 => key_event.set_chr('5' as _), + 94 => key_event.set_chr('6' as _), + 38 => key_event.set_chr('7' as _), + 42 => key_event.set_chr('8' as _), + 40 => key_event.set_chr('9' as _), + 41 => key_event.set_chr('0' as _), + 95 => key_event.set_chr('-' as _), + 43 => key_event.set_chr('=' as _), + 123 => key_event.set_chr('[' as _), + 125 => key_event.set_chr(']' as _), + 124 => key_event.set_chr('\\' as _), + 58 => key_event.set_chr(';' as _), + 34 => key_event.set_chr('\'' as _), + 60 => key_event.set_chr(',' as _), + 62 => key_event.set_chr('.' as _), + 63 => key_event.set_chr('/' as _), + _ => { + log::error!("Unknown key code {}", code); + return None; + } + } } else { log::error!("Unknown key code {}", code); return None; @@ -820,6 +860,17 @@ impl Handler { extended, ); + let mut name = name; + + if extended { + match name.as_ref() { + "VK_CONTROL" => name = "RControl".to_owned(), + "VK_MENU" => name = "RAlt".to_owned(), + "VK_SHIFT" => name = "RShift".to_owned(), + _ => {} + } + } + if let Some(mut key_event) = self.get_key_event(down_or_up, &name, code) { // Linux has different repeated key down handling from mac and windows /* // below cause hang some time, not find why, so disable. so shift + repeat char not work for mac->linux, win->linux works fine, linux->linux not test yet