From 7dfcc401e5d59b53e6243211639ef990cc4a2384 Mon Sep 17 00:00:00 2001 From: fufesou Date: Tue, 14 Feb 2023 15:42:02 +0800 Subject: [PATCH] translate mode, mac --> win, init debug Signed-off-by: fufesou --- Cargo.lock | 3 +- .../lib/desktop/widgets/remote_menubar.dart | 4 +- src/flutter_ffi.rs | 1 - src/keyboard.rs | 95 ++++++++++++++----- src/server/input_service.rs | 6 +- 5 files changed, 77 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0f66e287..2fcdef290 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4554,12 +4554,13 @@ dependencies = [ [[package]] name = "rdev" version = "0.5.0-2" -source = "git+https://github.com/fufesou/rdev#cedc4e62744566775026af4b434ef799804c1130" +source = "git+https://github.com/fufesou/rdev#593f0ba37139ed6f4f88a4120e972612ec4b1c6f" dependencies = [ "cocoa", "core-foundation 0.9.3", "core-foundation-sys 0.8.3", "core-graphics 0.22.3", + "dispatch", "enum-map", "epoll", "inotify", diff --git a/flutter/lib/desktop/widgets/remote_menubar.dart b/flutter/lib/desktop/widgets/remote_menubar.dart index 6bb49000b..9f8265fec 100644 --- a/flutter/lib/desktop/widgets/remote_menubar.dart +++ b/flutter/lib/desktop/widgets/remote_menubar.dart @@ -1510,8 +1510,8 @@ class _RemoteMenubarState extends State { if (bind.sessionIsKeyboardModeSupported( id: widget.id, mode: mode.key)) { if (mode.key == 'translate') { - if (!Platform.isWindows || - widget.ffi.ffiModel.pi.platform != kPeerPlatformWindows) { + if (Platform.isLinux || + widget.ffi.ffiModel.pi.platform == kPeerPlatformLinux) { continue; } } diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index b4e79b361..0e307abe3 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -20,7 +20,6 @@ use std::{ os::raw::c_char, str::FromStr, }; -use crate::ui_session_interface::InvokeUiSession; // use crate::hbbs_http::account::AuthResult; diff --git a/src/keyboard.rs b/src/keyboard.rs index 8aa5f72d2..7e4ba2b39 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -18,6 +18,13 @@ use std::{ #[cfg(windows)] static mut IS_ALT_GR: bool = false; +#[allow(dead_code)] +const OS_LOWER_WINDOWS: &str = "windows"; +#[allow(dead_code)] +const OS_LOWER_LINUX: &str = "linux"; +#[allow(dead_code)] +const OS_LOWER_MACOS: &str = "macos"; + #[cfg(any(target_os = "windows", target_os = "macos"))] static KEYBOARD_HOOKED: AtomicBool = AtomicBool::new(false); @@ -202,6 +209,9 @@ pub fn update_grab_get_key_name() { #[cfg(target_os = "windows")] static mut IS_0X021D_DOWN: bool = false; +#[cfg(target_os = "macos")] +static mut IS_LEFT_OPTION_DOWN: bool = false; + pub fn start_grab_loop() { #[cfg(any(target_os = "windows", target_os = "macos"))] std::thread::spawn(move || { @@ -213,6 +223,7 @@ pub fn start_grab_loop() { let mut _keyboard_mode = KeyboardMode::Map; let _scan_code = event.scan_code; + let _code = event.code; let res = if KEYBOARD_HOOKED.load(Ordering::SeqCst) { _keyboard_mode = client::process_event(&event, None); if is_press { @@ -246,6 +257,13 @@ pub fn start_grab_loop() { } } + #[cfg(target_os = "macos")] + unsafe { + if _code as u32 == rdev::kVK_Option { + IS_LEFT_OPTION_DOWN = is_press; + } + } + return res; }; let func = move |event: Event| match event.event_type { @@ -253,11 +271,13 @@ pub fn start_grab_loop() { EventType::KeyRelease(key) => try_handle_keyboard(event, key, false), _ => Some(event), }; + #[cfg(target_os = "macos")] + rdev::set_is_main_thread(false); + #[cfg(target_os = "windows")] + rdev::set_event_popup(false); if let Err(error) = rdev::grab(func) { log::error!("rdev Error: {:?}", error) } - #[cfg(target_os = "windows")] - rdev::set_event_popup(false); }); #[cfg(target_os = "linux")] @@ -395,13 +415,16 @@ pub fn event_to_key_events( _ => {} } + let mut peer = get_peer_platform().to_lowercase(); + peer.retain(|c| !c.is_whitespace()); + key_event.mode = keyboard_mode.into(); let mut key_events = match keyboard_mode { - KeyboardMode::Map => match map_keyboard_mode(event, key_event) { + KeyboardMode::Map => match map_keyboard_mode(peer.as_str(), event, key_event) { Some(event) => [event].to_vec(), None => Vec::new(), }, - KeyboardMode::Translate => translate_keyboard_mode(event, key_event), + KeyboardMode::Translate => translate_keyboard_mode(peer.as_str(), event, key_event), _ => { #[cfg(not(any(target_os = "android", target_os = "ios")))] { @@ -424,7 +447,6 @@ pub fn event_to_key_events( } } } - key_events } @@ -698,7 +720,7 @@ pub fn legacy_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Vec Option { +pub fn map_keyboard_mode(peer: &str, event: &Event, mut key_event: KeyEvent) -> Option { match event.event_type { EventType::KeyPress(..) => { key_event.down = true; @@ -709,12 +731,9 @@ pub fn map_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option return None, }; - let mut peer = get_peer_platform().to_lowercase(); - peer.retain(|c| !c.is_whitespace()); - #[cfg(target_os = "windows")] - let keycode = match peer.as_str() { - "windows" => { + let keycode = match peer { + OS_LOWER_WINDOWS => { // https://github.com/rustdesk/rustdesk/issues/1371 // Filter scancodes that are greater than 255 and the hight word is not 0xE0. if event.scan_code > 255 && (event.scan_code >> 8) != 0xE0 { @@ -722,7 +741,7 @@ pub fn map_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option { + OS_LOWER_MACOS => { if hbb_common::config::LocalConfig::get_kb_layout_type() == "ISO" { rdev::win_scancode_to_macos_iso_code(event.scan_code)? } else { @@ -732,15 +751,15 @@ pub fn map_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option rdev::win_scancode_to_linux_code(event.scan_code)?, }; #[cfg(target_os = "macos")] - let keycode = match peer.as_str() { - "windows" => rdev::macos_code_to_win_scancode(event.code as _)?, - "macos" => event.code as _, + let keycode = match peer { + OS_LOWER_WINDOWS => rdev::macos_code_to_win_scancode(event.code as _)?, + OS_LOWER_MACOS => event.code as _, _ => rdev::macos_code_to_linux_code(event.code as _)?, }; #[cfg(target_os = "linux")] - let keycode = match peer.as_str() { - "windows" => rdev::linux_code_to_win_scancode(event.code as _)?, - "macos" => { + let keycode = match peer { + OS_LOWER_WINDOWS => rdev::linux_code_to_win_scancode(event.code as _)?, + OS_LOWER_MACOS => { if hbb_common::config::LocalConfig::get_kb_layout_type() == "ISO" { rdev::linux_code_to_macos_iso_code(event.code as _)? } else { @@ -759,10 +778,10 @@ pub fn map_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option) { match &event.unicode { Some(unicode_info) => { - if let Some(name) = unicode_info.name { + if let Some(name) = &unicode_info.name { if name.len() > 0 { let mut evt = key_event.clone(); - evt.set_seq(name); + evt.set_seq(name.to_string()); events.push(evt); } } @@ -785,21 +804,42 @@ fn is_hot_key_modifiers_down() -> bool { return false; } -pub fn translate_vk_scan_code(event: &Event, mut key_event: KeyEvent) -> Option { +#[inline] +#[cfg(target_os = "windows")] +pub fn translate_key_code(event: &Event, mut key_event: KeyEvent) -> Option { let mut key_event = map_keyboard_mode(event, key_event)?; - #[cfg(target_os = "windows")] key_event.set_chr((key_event.chr() & 0x0000FFFF) | ((event.code as u32) << 16)); Some(key_event) } -pub fn translate_keyboard_mode(event: &Event, key_event: KeyEvent) -> Vec { +#[inline] +#[cfg(not(target_os = "windows"))] +pub fn translate_key_code(peer: &str, event: &Event, key_event: KeyEvent) -> Option { + map_keyboard_mode(peer, event, key_event) +} + +pub fn translate_keyboard_mode(peer: &str, event: &Event, key_event: KeyEvent) -> Vec { let mut events: Vec = Vec::new(); if let Some(unicode_info) = &event.unicode { if unicode_info.is_dead { + #[cfg(target_os = "macos")] + if peer != OS_LOWER_MACOS && unsafe { IS_LEFT_OPTION_DOWN } { + // try clear dead key state + // rdev::clear_dead_key_state(); + } else { + return events; + } + #[cfg(not(target_os = "macos"))] return events; } } + #[cfg(target_os = "macos")] + // ignore right option key + if event.code as u32 == rdev::kVK_RightOption { + return events; + } + #[cfg(target_os = "windows")] unsafe { if event.scan_code == 0x021D { @@ -825,11 +865,16 @@ pub fn translate_keyboard_mode(event: &Event, key_event: KeyEvent) -> Vec { - ENIGO.lock().unwrap().key_sequence(&seq); + ENIGO.lock().unwrap().key_sequence(seq); } Some(key_event::Union::Chr(..)) => { #[cfg(target_os = "windows")] translate_process_code(evt.chr(), evt.down); #[cfg(not(target_os = "windows"))] - sim_rdev_rawkey_position(code, down); + sim_rdev_rawkey_position(evt.chr(), evt.down); } Some(key_event::Union::Unicode(..)) => { // Do not handle unicode for now.