From 9771c652c59766bb63c560270dc3a64739cedd9b Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 25 Sep 2023 00:15:36 +0800 Subject: [PATCH] fix, alt + tab, switch window, release alt state Signed-off-by: fufesou --- flutter/lib/desktop/pages/remote_page.dart | 6 ++-- src/keyboard.rs | 36 ++++++++-------------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 305782e7a..13271378d 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -209,7 +209,7 @@ class _RemotePageState extends State debugPrint("REMOTE PAGE dispose session $sessionId ${widget.id}"); await _renderTexture.destroy(closeSession); // ensure we leave this session, this is a double check - bind.sessionEnterOrLeave(sessionId: sessionId, enter: false); + _ffi.inputModel.enterOrLeave(false); DesktopMultiWindow.removeListener(this); _ffi.dialogManager.hideMobileActionsOverlay(); _ffi.recordingModel.onClose(); @@ -329,7 +329,7 @@ class _RemotePageState extends State if (!_rawKeyFocusNode.hasFocus) { _rawKeyFocusNode.requestFocus(); } - bind.sessionEnterOrLeave(sessionId: sessionId, enter: true); + _ffi.inputModel.enterOrLeave(true); } } @@ -349,7 +349,7 @@ class _RemotePageState extends State } // See [onWindowBlur]. if (!Platform.isWindows) { - bind.sessionEnterOrLeave(sessionId: sessionId, enter: false); + _ffi.inputModel.enterOrLeave(false); } } diff --git a/src/keyboard.rs b/src/keyboard.rs index d79e396bf..72b0ff2f8 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -14,10 +14,8 @@ use rdev::KeyCode; use rdev::{Event, EventType, Key}; #[cfg(any(target_os = "windows", target_os = "macos"))] use std::sync::atomic::{AtomicBool, Ordering}; -#[cfg(not(any(target_os = "android", target_os = "ios")))] -use std::time::SystemTime; use std::{ - collections::{HashMap, HashSet}, + collections::HashMap, sync::{Arc, Mutex}, }; @@ -35,7 +33,7 @@ const OS_LOWER_MACOS: &str = "macos"; static KEYBOARD_HOOKED: AtomicBool = AtomicBool::new(false); lazy_static::lazy_static! { - static ref TO_RELEASE: Arc>> = Arc::new(Mutex::new(HashSet::::new())); + static ref TO_RELEASE: Arc>> = Arc::new(Mutex::new(HashMap::new())); static ref MODIFIERS_STATE: Mutex> = { let mut m = HashMap::new(); m.insert(Key::ShiftLeft, false); @@ -336,12 +334,17 @@ 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(); - for key in to_release { - let event_type = EventType::KeyRelease(key); - let event = event_type_to_event(event_type); - // to-do: BUG - // Release events should be sent to the corresponding sessions, instead of current session. + for (key, mut event) in to_release.into_iter() { + event.event_type = EventType::KeyRelease(key); client::process_event(keyboard_mode, &event, None); + // If Alt or AltGr is pressed, we need to send another key stoke to release it. + // Because the controlled side may hold the alt state, if local window is switched by [Alt + Tab]. + if key == Key::Alt || key == Key::AltGr { + event.event_type = EventType::KeyPress(key); + client::process_event(keyboard_mode, &event, None); + event.event_type = EventType::KeyRelease(key); + client::process_event(keyboard_mode, &event, None); + } } } @@ -519,7 +522,7 @@ pub fn event_to_key_events( match event.event_type { EventType::KeyPress(key) => { - TO_RELEASE.lock().unwrap().insert(key); + TO_RELEASE.lock().unwrap().insert(key, event.clone()); } EventType::KeyRelease(key) => { TO_RELEASE.lock().unwrap().remove(&key); @@ -570,19 +573,6 @@ pub fn event_to_key_events( key_events } -#[cfg(not(any(target_os = "android", target_os = "ios")))] -pub fn event_type_to_event(event_type: EventType) -> Event { - Event { - event_type, - time: SystemTime::now(), - unicode: None, - platform_code: 0, - position_code: 0, - #[cfg(any(target_os = "windows", target_os = "macos"))] - extra_data: 0, - } -} - pub fn send_key_event(key_event: &KeyEvent) { #[cfg(not(any(feature = "flutter", feature = "cli")))] if let Some(session) = CUR_SESSION.lock().unwrap().as_ref() {