From 34d7089a8e2c8c0260932b9992924467e1daf577 Mon Sep 17 00:00:00 2001 From: Asura Date: Fri, 2 Sep 2022 04:49:36 -0700 Subject: [PATCH] Refactor: map keyboard --- flutter/lib/desktop/pages/remote_page.dart | 8 ++-- flutter/lib/models/model.dart | 12 ++++-- src/flutter_ffi.rs | 31 ++++++++++---- src/ui_session_interface.rs | 50 ++++++++++++++++++---- 4 files changed, 75 insertions(+), 26 deletions(-) diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index c3f4b3773..51225672b 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -291,13 +291,13 @@ class _RemotePageState extends State keyCode = -1; } - if (e is RawKeyDownEvent){ + if (e is RawKeyDownEvent) { down = true; - }else{ + } else { down = false; } - - _ffi.inputRawKey(keyCode, scanCode, down); + + _ffi.inputRawKey(e.character ?? "", keyCode, scanCode, down); } void legacyKeyboardMode(RawKeyEvent e) { diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 967a334e8..dcf9a7b22 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -993,10 +993,14 @@ class FFI { msg: json.encode(modify({'type': type, 'buttons': button.value}))); } - // Raw Key - void inputRawKey(int keyCode, int scanCode, bool down){ - debugPrint(scanCode.toString()); - // bind.sessionInputRawKey(id: id, keycode: keyCode, scancode: scanCode, down: down); + // Raw Key + void inputRawKey(String name, int keyCode, int scanCode, bool down) { + bind.sessionHandleFlutterKeyEvent( + id: id, + name: name, + keycode: keyCode, + scancode: scanCode, + downOrUp: down); } /// Send key stroke event. diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 78f53bf89..72ccbe603 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -7,20 +7,19 @@ use std::{ use flutter_rust_bridge::{StreamSink, SyncReturn, ZeroCopyBuffer}; use serde_json::json; +use hbb_common::ResultType; use hbb_common::{ config::{self, LocalConfig, PeerConfig, ONLINE}, fs, log, }; -use hbb_common::{ResultType}; -use crate::{client::file_trait::FileManager, flutter::{session_add, session_start_}}; use crate::common::make_fd_to_json; use crate::flutter::connection_manager::{self, get_clients_length, get_clients_state}; use crate::flutter::{self, SESSIONS}; use crate::start_server; use crate::ui_interface; #[cfg(not(any(target_os = "android", target_os = "ios")))] -use crate::ui_interface::{change_id}; +use crate::ui_interface::change_id; use crate::ui_interface::{ check_mouse_time, check_super_user_permission, discover, forget_password, get_api_server, get_app_name, get_async_job_status, get_connect_status, get_fav, get_id, get_lan_peers, @@ -30,6 +29,10 @@ use crate::ui_interface::{ set_peer_option, set_permanent_password, set_socks, store_fav, test_if_valid_server, update_temporary_password, using_public_server, }; +use crate::{ + client::file_trait::FileManager, + flutter::{session_add, session_start_}, +}; fn initialize(app_dir: &str) { *config::APP_DIR.write().unwrap() = app_dir.to_owned(); @@ -110,7 +113,11 @@ pub fn host_stop_system_key_propagate(stopped: bool) { // FIXME: -> ResultType<()> cannot be parsed by frb_codegen // thread 'main' panicked at 'Failed to parse function output type `ResultType<()>`', $HOME\.cargo\git\checkouts\flutter_rust_bridge-ddba876d3ebb2a1e\e5adce5\frb_codegen\src\parser\mod.rs:151:25 -pub fn session_add_sync(id: String, is_file_transfer: bool, is_port_forward: bool) -> SyncReturn { +pub fn session_add_sync( + id: String, + is_file_transfer: bool, + is_port_forward: bool, +) -> SyncReturn { if let Err(e) = session_add(&id, is_file_transfer, is_port_forward) { SyncReturn(format!("Failed to add session with id {}, {}", &id, e)) } else { @@ -228,11 +235,17 @@ pub fn session_switch_display(id: String, value: i32) { } } -// pub fn session_input_raw_key(id: String, keycode: i32, scancode:i32, down: bool){ -// if let Some(session) = SESSIONS.read().unwrap().get(&id) { -// session.input_raw_key(keycode, scancode, down); -// } -// } +pub fn session_handle_flutter_key_event( + id: String, + name: String, + keycode: i32, + scancode: i32, + down_or_up: bool, +) { + if let Some(session) = SESSIONS.read().unwrap().get(&id) { + session.handle_flutter_key_event(&name, keycode, scancode, down_or_up); + } +} pub fn session_input_key( id: String, diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 4f5ec55b8..7143ed97a 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -57,13 +57,13 @@ impl Session { self.lc.read().unwrap().custom_image_quality.clone() } - pub fn get_keyboard_mode(&mut self) -> String { + pub fn get_keyboard_mode(&self) -> String { return std::env::var("KEYBOARD_MODE") .unwrap_or(String::from("legacy")) .to_lowercase(); } - pub fn save_keyboard_mode(&mut self, value: String) { + pub fn save_keyboard_mode(&self, value: String) { std::env::set_var("KEYBOARD_MODE", value); } @@ -272,7 +272,7 @@ impl Session { } #[allow(dead_code)] - fn convert_numpad_keys(&mut self, key: RdevKey) -> RdevKey { + fn convert_numpad_keys(&self, key: RdevKey) -> RdevKey { if get_key_state(enigo::Key::NumLock) { return key; } @@ -292,7 +292,7 @@ impl Session { } } - fn map_keyboard_mode(&mut self, down_or_up: bool, key: RdevKey, _evt: Option) { + fn map_keyboard_mode(&self, down_or_up: bool, key: RdevKey, _evt: Option) { // map mode(1): Send keycode according to the peer platform. #[cfg(target_os = "windows")] let key = if let Some(e) = _evt { @@ -328,11 +328,12 @@ impl Session { if get_key_state(enigo::Key::NumLock) { key_event.modifiers.push(ControlKey::NumLock.into()); } + log::info!("{:?}", get_key_state(enigo::Key::NumLock)); self.send_key_event(key_event, KeyboardMode::Map); } - fn translate_keyboard_mode(&mut self, down_or_up: bool, key: RdevKey, evt: Event) { + fn translate_keyboard_mode(&self, down_or_up: bool, key: RdevKey, evt: Event) { // translate mode(2): locally generated characters are send to the peer. // get char @@ -423,7 +424,7 @@ impl Session { } } - fn legacy_keyboard_mode(&mut self, down_or_up: bool, key: RdevKey, evt: Event) { + fn legacy_keyboard_mode(&self, down_or_up: bool, key: RdevKey, evt: Event) { // legacy mode(0): Generate characters locally, look for keycode on other side. let peer = self.peer_platform(); let is_win = peer == "Windows"; @@ -635,7 +636,7 @@ impl Session { self.send_key_event(key_event, KeyboardMode::Legacy) } - fn key_down_or_up(&mut self, down_or_up: bool, key: RdevKey, evt: Event) { + fn key_down_or_up(&self, down_or_up: bool, key: RdevKey, evt: Event) { // Call different functions according to keyboard mode. let mode = match self.get_keyboard_mode().as_str() { "map" => KeyboardMode::Map, @@ -724,6 +725,35 @@ impl Session { self.send_key_event(key_event, KeyboardMode::Legacy); } + pub fn handle_flutter_key_event(&self, name: &str, keycode: i32, scancode:i32, down_or_up: bool){ + if scancode < 0 || keycode < 0{ + return; + } + let keycode: u32 = keycode as u32; + let scancode: u32 = scancode as u32; + + #[cfg(not(target_os = "windows"))] + let key = rdev::key_from_scancode(scancode) as RdevKey; + // Windows requires special handling + #[cfg(target_os = "windows")] + let key = rdev::get_win_key(keycode, scancode); + + let event_type = if down_or_up{ + KeyPress(key) + }else{ + KeyRelease(key) + }; + let evt = Event{ + time: std::time::SystemTime::now(), + name: Option::Some(name.to_owned()), + code: keycode as _, + scan_code: scancode as _, + event_type: event_type, + }; + + self.key_down_or_up(down_or_up, key, evt) + } + // flutter only TODO new input pub fn input_key( &self, @@ -796,8 +826,10 @@ impl Session { } } } - // asur4s-todo - // self.key_down_or_up(v, key_event, alt, ctrl, shift, command); + + self.legacy_modifiers(&mut key_event, true, true, false, false); + key_event.press = down; + self.send_key_event(key_event, KeyboardMode::Legacy); } pub fn send_mouse(