From 0f72af652973f1c65c2476a24f3d9db5b62d81d3 Mon Sep 17 00:00:00 2001 From: asur4s Date: Wed, 29 Mar 2023 00:40:05 -0700 Subject: [PATCH 1/3] Release modifier when multi conn --- src/keyboard.rs | 25 ++++++++++++++++++++++ src/platform/mod.rs | 2 +- src/server/connection.rs | 42 ++++++++++++++++++++++++++++++++++++- src/server/input_service.rs | 2 +- 4 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/keyboard.rs b/src/keyboard.rs index 294e058c5..0e271a0b6 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -365,6 +365,21 @@ pub fn get_keyboard_mode_enum() -> KeyboardMode { } } +#[inline] +pub fn is_modifier(key: &rdev::Key) -> bool { + matches!( + key, + Key::ShiftLeft + | Key::ShiftRight + | Key::ControlLeft + | Key::ControlRight + | Key::MetaLeft + | Key::MetaRight + | Key::Alt + | Key::AltGr + ) +} + #[inline] #[cfg(not(any(target_os = "android", target_os = "ios")))] fn is_numpad_key(event: &Event) -> bool { @@ -984,3 +999,13 @@ pub fn translate_keyboard_mode(peer: &str, event: &Event, key_event: KeyEvent) - } events } + +#[cfg(not(any(target_os = "android", target_os = "ios")))] +pub fn keycode_to_rdev_key(keycode: u32) -> Key { + #[cfg(target_os = "windows")] + return rdev::win_key_from_scancode(keycode); + #[cfg(target_os = "linux")] + return rdev::linux_key_from_code(keycode); + #[cfg(target_os = "macos")] + return rdev::macos_key_from_code(keycode.try_into().unwrap_or_default()); +} diff --git a/src/platform/mod.rs b/src/platform/mod.rs index f8fe7a6dd..777de3b01 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -37,7 +37,7 @@ pub fn breakdown_callback() { #[cfg(target_os = "linux")] crate::input_service::clear_remapped_keycode(); #[cfg(not(any(target_os = "android", target_os = "ios")))] - crate::input_service::release_modifiers(); + crate::input_service::release_device_modifiers(); } // Android diff --git a/src/server/connection.rs b/src/server/connection.rs index 0c17fd176..dbda219e0 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -10,6 +10,7 @@ use crate::{ new_voice_call_request, new_voice_call_response, start_audio_thread, MediaData, MediaSender, }, common::{get_default_sound_input, set_sound_input}, + keyboard::{is_modifier, keycode_to_rdev_key}, video_service, }; #[cfg(any(target_os = "android", target_os = "ios"))] @@ -39,6 +40,7 @@ use sha2::{Digest, Sha256}; #[cfg(not(any(target_os = "android", target_os = "ios")))] use std::sync::atomic::Ordering; use std::{ + collections::HashSet, num::NonZeroI64, sync::{atomic::AtomicI64, mpsc as std_mpsc}, }; @@ -132,6 +134,7 @@ pub struct Connection { voice_call_request_timestamp: Option, audio_input_device_before_voice_call: Option, options_in_login: Option, + pressed_modifiers: HashSet, } impl ConnInner { @@ -243,6 +246,7 @@ impl Connection { voice_call_request_timestamp: None, audio_input_device_before_voice_call: None, options_in_login: None, + pressed_modifiers: Default::default(), }; #[cfg(not(any(target_os = "android", target_os = "ios")))] tokio::spawn(async move { @@ -618,7 +622,6 @@ impl Connection { } #[cfg(target_os = "linux")] clear_remapped_keycode(); - release_modifiers(); log::info!("Input thread exited"); } @@ -1366,6 +1369,28 @@ impl Connection { } else { me.press }; + + let key = match me.mode.unwrap() { + KeyboardMode::Map => Some(keycode_to_rdev_key(me.chr())), + KeyboardMode::Translate => { + if let Some(key_event::Union::Chr(code)) = me.union.clone() { + Some(keycode_to_rdev_key(code & 0x0000FFFF)) + } else { + None + } + } + _ => None, + } + .filter(is_modifier); + + if let Some(key) = key { + if is_press { + self.pressed_modifiers.insert(key); + } else { + self.pressed_modifiers.remove(&key); + } + } + if is_press { match me.union { Some(key_event::Union::Unicode(_)) @@ -2023,6 +2048,14 @@ impl Connection { }) .count(); } + + #[cfg(not(any(target_os = "android", target_os = "ios")))] + fn release_pressed_modifiers(&mut self) { + for modifier in self.pressed_modifiers.iter() { + rdev::simulate(&rdev::EventType::KeyRelease(*modifier)).ok(); + } + self.pressed_modifiers.clear(); + } } pub fn insert_switch_sides_uuid(id: String, uuid: uuid::Uuid) { @@ -2220,3 +2253,10 @@ impl Default for PortableState { } } } + +impl Drop for Connection { + fn drop(&mut self) { + #[cfg(not(any(target_os = "android", target_os = "ios")))] + self.release_pressed_modifiers(); + } +} diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 25b41d0ef..5bc486516 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -551,7 +551,7 @@ fn record_key_to_key(record_key: u64) -> Option { } } -pub fn release_modifiers() { +pub fn release_device_modifiers() { let mut en = ENIGO.lock().unwrap(); for modifier in [ Key::Shift, From 0312e734c06aba56ddc09bd2128da05710d0509c Mon Sep 17 00:00:00 2001 From: chiehw Date: Fri, 31 Mar 2023 14:18:55 +0800 Subject: [PATCH 2/3] fix build --- src/lang.rs | 2 +- src/server/connection.rs | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lang.rs b/src/lang.rs index 972510325..4776eb89e 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -5,12 +5,12 @@ mod cn; mod cs; mod da; mod de; +mod el; mod en; mod eo; mod es; mod fa; mod fr; -mod el; mod hu; mod id; mod it; diff --git a/src/server/connection.rs b/src/server/connection.rs index dbda219e0..eecfaa20c 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -10,7 +10,6 @@ use crate::{ new_voice_call_request, new_voice_call_response, start_audio_thread, MediaData, MediaSender, }, common::{get_default_sound_input, set_sound_input}, - keyboard::{is_modifier, keycode_to_rdev_key}, video_service, }; #[cfg(any(target_os = "android", target_os = "ios"))] @@ -1371,17 +1370,17 @@ impl Connection { }; let key = match me.mode.unwrap() { - KeyboardMode::Map => Some(keycode_to_rdev_key(me.chr())), + KeyboardMode::Map => Some(crate::keyboard::keycode_to_rdev_key(me.chr())), KeyboardMode::Translate => { if let Some(key_event::Union::Chr(code)) = me.union.clone() { - Some(keycode_to_rdev_key(code & 0x0000FFFF)) + Some(crate::keyboard::keycode_to_rdev_key(code & 0x0000FFFF)) } else { None } } _ => None, } - .filter(is_modifier); + .filter(crate::keyboard::is_modifier); if let Some(key) = key { if is_press { From 726884f1f3890cc6072da5c6d4611b56f6e8ca48 Mon Sep 17 00:00:00 2001 From: chiehw Date: Sat, 1 Apr 2023 01:12:41 +0800 Subject: [PATCH 3/3] Fix review --- src/server/connection.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/server/connection.rs b/src/server/connection.rs index eecfaa20c..b25c5b1e7 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1369,10 +1369,12 @@ impl Connection { me.press }; - let key = match me.mode.unwrap() { - KeyboardMode::Map => Some(crate::keyboard::keycode_to_rdev_key(me.chr())), + let key = match me.mode.enum_value_or_default() { + KeyboardMode::Map => { + Some(crate::keyboard::keycode_to_rdev_key(me.chr())) + } KeyboardMode::Translate => { - if let Some(key_event::Union::Chr(code)) = me.union.clone() { + if let Some(key_event::Union::Chr(code)) = me.union { Some(crate::keyboard::keycode_to_rdev_key(code & 0x0000FFFF)) } else { None