From ae3efa115134aa9a742669f4b67d2d36dcb6be93 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sun, 17 Sep 2023 13:01:27 +0800 Subject: [PATCH] fix, RwLock, remove nested read calls Signed-off-by: fufesou --- src/common.rs | 18 --------- src/flutter_ffi.rs | 23 +++++++---- src/keyboard.rs | 79 +++++++++++++++++-------------------- src/ui_session_interface.rs | 36 ++++++++--------- 4 files changed, 69 insertions(+), 87 deletions(-) diff --git a/src/common.rs b/src/common.rs index 8477c9e62..4146827e8 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1042,24 +1042,6 @@ pub async fn get_key(sync: bool) -> String { key } -pub fn is_peer_version_ge(v: &str) -> bool { - #[cfg(not(any(feature = "flutter", feature = "cli")))] - if let Some(session) = crate::ui::CUR_SESSION.lock().unwrap().as_ref() { - return session.get_peer_version() >= hbb_common::get_version_number(v); - } - - #[cfg(feature = "flutter")] - if let Some(session) = crate::flutter::SESSIONS - .read() - .unwrap() - .get(&*crate::flutter::CUR_SESSION_ID.read().unwrap()) - { - return session.get_peer_version() >= hbb_common::get_version_number(v); - } - - false -} - pub fn pk_to_fingerprint(pk: Vec) -> String { let s: String = pk.iter().map(|u| format!("{:02x}", u)).collect(); s.chars() diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index c9da2cde2..2f3280c52 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -1,5 +1,3 @@ -use hbb_common::config::Config; - #[cfg(not(any(target_os = "android", target_os = "ios")))] use crate::common::get_default_sound_input; use crate::{ @@ -293,12 +291,12 @@ pub fn session_get_keyboard_mode(session_id: SessionID) -> Option { pub fn session_set_keyboard_mode(session_id: SessionID, value: String) { let mut _mode_updated = false; if let Some(session) = SESSIONS.write().unwrap().get_mut(&session_id) { - session.save_keyboard_mode(value); + session.save_keyboard_mode(value.clone()); _mode_updated = true; } #[cfg(windows)] if _mode_updated { - crate::keyboard::update_grab_get_key_name(); + crate::keyboard::update_grab_get_key_name(&value); } } @@ -378,7 +376,9 @@ pub fn session_handle_flutter_key_event( down_or_up: bool, ) { if let Some(session) = SESSIONS.read().unwrap().get(&session_id) { + let keyboard_mode = session.get_keyboard_mode(); session.handle_flutter_key_event( + &keyboard_mode, &name, platform_code, position_code, @@ -397,11 +397,12 @@ pub fn session_handle_flutter_key_event( pub fn session_enter_or_leave(_session_id: SessionID, _enter: bool) -> SyncReturn<()> { #[cfg(not(any(target_os = "android", target_os = "ios")))] if let Some(session) = SESSIONS.read().unwrap().get(&_session_id) { + let keyboard_mode = session.get_keyboard_mode(); if _enter { - set_cur_session_id(_session_id); - session.enter(); + set_cur_session_id_(_session_id, &keyboard_mode); + session.enter(&keyboard_mode); } else { - session.leave(); + session.leave(&keyboard_mode); } } SyncReturn(()) @@ -1509,9 +1510,15 @@ pub fn main_update_me() -> SyncReturn { } pub fn set_cur_session_id(session_id: SessionID) { + if let Some(session) = SESSIONS.read().unwrap().get(&session_id) { + set_cur_session_id_(session_id, &session.get_keyboard_mode()) + } +} + +fn set_cur_session_id_(session_id: SessionID, keyboard_mode: &str) { super::flutter::set_cur_session_id(session_id); #[cfg(windows)] - crate::keyboard::update_grab_get_key_name(); + crate::keyboard::update_grab_get_key_name(keyboard_mode); } pub fn install_show_run_without_install() -> SyncReturn { diff --git a/src/keyboard.rs b/src/keyboard.rs index d9b562ed3..d79e396bf 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -56,22 +56,6 @@ pub mod client { static ref IS_GRAB_STARTED: Arc> = Arc::new(Mutex::new(false)); } - pub fn get_keyboard_mode() -> String { - #[cfg(not(any(feature = "flutter", feature = "cli")))] - if let Some(session) = CUR_SESSION.lock().unwrap().as_ref() { - return session.get_keyboard_mode(); - } - #[cfg(feature = "flutter")] - if let Some(session) = SESSIONS - .read() - .unwrap() - .get(&*CUR_SESSION_ID.read().unwrap()) - { - return session.get_keyboard_mode(); - } - "legacy".to_string() - } - pub fn start_grab_loop() { let mut lock = IS_GRAB_STARTED.lock().unwrap(); if *lock { @@ -82,12 +66,12 @@ pub mod client { } #[cfg(not(any(target_os = "android", target_os = "ios")))] - pub fn change_grab_status(state: GrabState) { + pub fn change_grab_status(state: GrabState, keyboard_mode: &str) { match state { GrabState::Ready => {} GrabState::Run => { #[cfg(windows)] - update_grab_get_key_name(); + update_grab_get_key_name(keyboard_mode); #[cfg(any(target_os = "windows", target_os = "macos"))] KEYBOARD_HOOKED.swap(true, Ordering::SeqCst); @@ -95,7 +79,10 @@ pub mod client { rdev::enable_grab(); } GrabState::Wait => { - release_remote_keys(); + #[cfg(windows)] + rdev::set_get_key_unicode(false); + + release_remote_keys(keyboard_mode); #[cfg(any(target_os = "windows", target_os = "macos"))] KEYBOARD_HOOKED.swap(false, Ordering::SeqCst); @@ -110,17 +97,16 @@ pub mod client { } } - pub fn process_event(event: &Event, lock_modes: Option) -> KeyboardMode { - let keyboard_mode = get_keyboard_mode_enum(); + pub fn process_event(keyboard_mode: &str, event: &Event, lock_modes: Option) { + let keyboard_mode = get_keyboard_mode_enum(keyboard_mode); if is_long_press(&event) { - return keyboard_mode; + return; } for key_event in event_to_key_events(&event, keyboard_mode, lock_modes) { send_key_event(&key_event); } - keyboard_mode } pub fn get_modifiers_state( @@ -215,10 +201,11 @@ pub mod client { } #[cfg(windows)] -pub fn update_grab_get_key_name() { - match get_keyboard_mode_enum() { - KeyboardMode::Map => rdev::set_get_key_unicode(false), - KeyboardMode::Translate => rdev::set_get_key_unicode(true), +pub fn update_grab_get_key_name(keyboard_mode: &str) { + match keyboard_mode { + "map" => rdev::set_get_key_unicode(false), + "translate" => rdev::set_get_key_unicode(true), + "legacy" => rdev::set_get_key_unicode(true), _ => {} }; } @@ -229,6 +216,22 @@ static mut IS_0X021D_DOWN: bool = false; #[cfg(target_os = "macos")] static mut IS_LEFT_OPTION_DOWN: bool = false; +fn get_keyboard_mode() -> String { + #[cfg(not(any(feature = "flutter", feature = "cli")))] + if let Some(session) = CUR_SESSION.lock().unwrap().as_ref() { + return session.get_keyboard_mode(); + } + #[cfg(feature = "flutter")] + if let Some(session) = SESSIONS + .read() + .unwrap() + .get(&*CUR_SESSION_ID.read().unwrap()) + { + return session.get_keyboard_mode(); + } + "legacy".to_string() +} + pub fn start_grab_loop() { std::env::set_var("KEYBOARD_ONLY", "y"); #[cfg(any(target_os = "windows", target_os = "macos"))] @@ -239,11 +242,10 @@ pub fn start_grab_loop() { return Some(event); } - let mut _keyboard_mode = KeyboardMode::Map; let _scan_code = event.position_code; let _code = event.platform_code as KeyCode; let res = if KEYBOARD_HOOKED.load(Ordering::SeqCst) { - _keyboard_mode = client::process_event(&event, None); + client::process_event(&get_keyboard_mode(), &event, None); if is_press { None } else { @@ -304,7 +306,7 @@ pub fn start_grab_loop() { if let Key::Unknown(keycode) = key { log::error!("rdev get unknown key, keycode is : {:?}", keycode); } else { - client::process_event(&event, None); + client::process_event(&get_keyboard_mode(), &event, None); } None } @@ -330,7 +332,7 @@ pub fn is_long_press(event: &Event) -> bool { } #[cfg(not(any(target_os = "android", target_os = "ios")))] -pub fn release_remote_keys() { +pub fn release_remote_keys(keyboard_mode: &str) { // todo!: client quit suddenly, how to release keys? let to_release = TO_RELEASE.lock().unwrap().clone(); TO_RELEASE.lock().unwrap().clear(); @@ -339,23 +341,16 @@ pub fn release_remote_keys() { let event = event_type_to_event(event_type); // to-do: BUG // Release events should be sent to the corresponding sessions, instead of current session. - client::process_event(&event, None); + client::process_event(keyboard_mode, &event, None); } } -pub fn get_keyboard_mode_enum() -> KeyboardMode { - match client::get_keyboard_mode().as_str() { +pub fn get_keyboard_mode_enum(keyboard_mode: &str) -> KeyboardMode { + match keyboard_mode { "map" => KeyboardMode::Map, "translate" => KeyboardMode::Translate, "legacy" => KeyboardMode::Legacy, - _ => { - // Set "map" as default mode if version >= 1.2.0. - if crate::is_peer_version_ge("1.2.0") { - KeyboardMode::Map - } else { - KeyboardMode::Legacy - } - } + _ => KeyboardMode::Map, } } diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 6d12e7a1e..7072f75ec 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -168,7 +168,17 @@ impl Session { } pub fn get_keyboard_mode(&self) -> String { - self.lc.read().unwrap().keyboard_mode.clone() + let mode = self.lc.read().unwrap().keyboard_mode.clone(); + if ["map", "translate", "legacy"].contains(&(&mode as &str)) { + mode + } else { + if self.get_peer_version() > hbb_common::get_version_number("1.2.0") { + "map" + } else { + "legacy" + } + .to_string() + } } pub fn save_keyboard_mode(&mut self, value: String) { @@ -562,28 +572,15 @@ impl Session { } #[cfg(not(any(target_os = "android", target_os = "ios")))] - pub fn enter(&self) { - #[cfg(target_os = "windows")] - { - match &self.lc.read().unwrap().keyboard_mode as _ { - "legacy" => rdev::set_get_key_unicode(true), - "translate" => rdev::set_get_key_unicode(true), - _ => {} - } - } - + pub fn enter(&self, keyboard_mode: &str) { IS_IN.store(true, Ordering::SeqCst); - keyboard::client::change_grab_status(GrabState::Run); + keyboard::client::change_grab_status(GrabState::Run, keyboard_mode); } #[cfg(not(any(target_os = "android", target_os = "ios")))] - pub fn leave(&self) { - #[cfg(target_os = "windows")] - { - rdev::set_get_key_unicode(false); - } + pub fn leave(&self, keyboard_mode: &str) { IS_IN.store(false, Ordering::SeqCst); - keyboard::client::change_grab_status(GrabState::Wait); + keyboard::client::change_grab_status(GrabState::Wait, keyboard_mode); } // flutter only TODO new input @@ -631,6 +628,7 @@ impl Session { #[cfg(not(any(target_os = "ios")))] pub fn handle_flutter_key_event( &self, + keyboard_mode: &str, _name: &str, platform_code: i32, position_code: i32, @@ -663,7 +661,7 @@ impl Session { #[cfg(any(target_os = "windows", target_os = "macos"))] extra_data: 0, }; - keyboard::client::process_event(&event, Some(lock_modes)); + keyboard::client::process_event(keyboard_mode, &event, Some(lock_modes)); } // flutter only TODO new input