diff --git a/Cargo.lock b/Cargo.lock index d8c112fd6..dc1244525 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -254,9 +254,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.8.0" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "bytemuck" @@ -409,9 +409,9 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.46" +version = "0.1.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b858541263efe664aead4a5209a4ae5c5d2811167d4ed4ee0944503f8d2089" +checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" dependencies = [ "cc", ] @@ -1015,9 +1015,9 @@ dependencies = [ [[package]] name = "flexi_logger" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11be38a063886b7be57de89636d65c07d318c1f9bd985cd8ab2c343786a910bc" +checksum = "a2917b8937f4d36d9df8b15a51428b6a1b2726ec57402b0c94b4dfc393a409e5" dependencies = [ "ansi_term", "atty", @@ -3091,6 +3091,7 @@ dependencies = [ "sha2", "sys-locale", "systray", + "tigervnc", "uuid", "whoami", "winapi 0.3.9", @@ -3309,9 +3310,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900d964dd36bb15bcf2f2b35694c072feab74969a54f2bbeec7a2d725d2bdcb6" +checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -3458,9 +3459,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.84" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b" +checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" dependencies = [ "proc-macro2", "quote", @@ -3603,6 +3604,15 @@ dependencies = [ "weezl", ] +[[package]] +name = "tigervnc" +version = "1.0.1" +source = "git+https://github.com/open-trade/tigervnc#254ad243c5a22887ddf0e79def58b8251b108d08" +dependencies = [ + "cc", + "cfg-if 1.0.0", +] + [[package]] name = "time" version = "0.3.5" @@ -4150,18 +4160,18 @@ dependencies = [ [[package]] name = "zstd" -version = "0.9.1+zstd.1.5.1" +version = "0.9.2+zstd.1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "538b8347df9257b7fbce37677ef7535c00a3c7bf1f81023cc328ed7fe4b41de8" +checksum = "2390ea1bf6c038c39674f22d95f0564725fc06034a47129179810b2fc58caa54" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "4.1.2+zstd.1.5.1" +version = "4.1.3+zstd.1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb4cfe2f6e6d35c5d27ecd9d256c4b6f7933c4895654917460ec56c29336cc1" +checksum = "e99d81b99fb3c2c2c794e3fe56c305c63d5173a16a46b5850b07c935ffc7db79" dependencies = [ "libc", "zstd-sys", diff --git a/Cargo.toml b/Cargo.toml index d5029532f..69b3673ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ sciter-rs = { git = "https://github.com/open-trade/rust-sciter", branch = "dyn" ctrlc = "3.2" arboard = "2.0" clipboard-master = "3.1" +tigervnc = { git = "https://github.com/open-trade/tigervnc" } [target.'cfg(target_os = "windows")'.dependencies] systray = { git = "https://github.com/liyue201/systray-rs" } diff --git a/libs/enigo/src/lib.rs b/libs/enigo/src/lib.rs index 893f5918c..10c5da4a7 100644 --- a/libs/enigo/src/lib.rs +++ b/libs/enigo/src/lib.rs @@ -418,6 +418,8 @@ pub enum Key { Layout(char), /// raw keycode eg 0x38 Raw(u16), + /// VNC keysym + KeySym(u32), } /// Representing an interface and a set of keyboard functions every diff --git a/libs/enigo/src/linux.rs b/libs/enigo/src/linux.rs index 24628c1f9..be21a2c70 100644 --- a/libs/enigo/src/linux.rs +++ b/libs/enigo/src/linux.rs @@ -181,6 +181,9 @@ impl MouseControllable for Enigo { } } fn keysequence<'a>(key: Key) -> Cow<'a, str> { + if let Key::KeySym(sym) = key { + return Cow::Owned("".to_owned()); + } if let Key::Layout(c) = key { return Cow::Owned(format!("U{:X}", c as u32)); } diff --git a/libs/enigo/src/macos/macos_impl.rs b/libs/enigo/src/macos/macos_impl.rs index 0ee038012..93b78c6d8 100644 --- a/libs/enigo/src/macos/macos_impl.rs +++ b/libs/enigo/src/macos/macos_impl.rs @@ -426,6 +426,7 @@ impl Enigo { Key::Raw(raw_keycode) => raw_keycode, Key::Layout(c) => self.map_key_board(c), + Key::KeySym(sym) => 0 as _, Key::Super | Key::Command | Key::Windows | Key::Meta => kVK_Command, _ => 0, diff --git a/libs/enigo/src/win/win_impl.rs b/libs/enigo/src/win/win_impl.rs index 3a6b6215f..3f83dc951 100644 --- a/libs/enigo/src/win/win_impl.rs +++ b/libs/enigo/src/win/win_impl.rs @@ -340,6 +340,7 @@ impl Enigo { Key::Raw(raw_keycode) => raw_keycode, Key::Layout(c) => self.get_layoutdependent_keycode(c.to_string()), Key::Super | Key::Command | Key::Windows | Key::Meta => EVK_LWIN, + Key::KeySym(sym) => 0, } } diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index 24bc189b2..47c526dd1 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -172,6 +172,7 @@ message KeyEvent { uint32 chr = 4; uint32 unicode = 5; string seq = 6; + uint32 keysym = 7; } repeated ControlKey modifiers = 8; } diff --git a/src/client.rs b/src/client.rs index ef6b00d76..e6a5d0afd 100644 --- a/src/client.rs +++ b/src/client.rs @@ -134,8 +134,7 @@ impl Client { log::info!("rendezvous server: {}", rendezvous_server); let mut socket = - socket_client::connect_tcp(&*rendezvous_server, any_addr, RENDEZVOUS_TIMEOUT) - .await?; + socket_client::connect_tcp(&*rendezvous_server, any_addr, RENDEZVOUS_TIMEOUT).await?; let my_addr = socket.local_addr(); let mut pk = Vec::new(); let mut relay_server = "".to_owned(); @@ -682,6 +681,7 @@ pub struct LoginConfigHandler { pub port_forward: (String, i32), pub support_press: bool, pub support_refresh: bool, + pub internation_keyboard: bool, } impl Deref for LoginConfigHandler { @@ -938,6 +938,7 @@ impl LoginConfigHandler { if !pi.version.is_empty() { self.support_press = true; self.support_refresh = true; + self.internation_keyboard = crate::get_version_number(&pi.version) > 1001008; } let serde = PeerInfoSerde { username, diff --git a/src/server/input_service.rs b/src/server/input_service.rs index ba34772a5..ef06f2348 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -40,7 +40,8 @@ struct Input { time: i64, } -const KEY_CHAR_START: i32 = 9999; +const KEY_CHAR_START: u64 = 0xFFFF; +const KEY_SYM_START: u64 = 0xFFFFFFFF; #[derive(Clone, Default)] pub struct MouseCursorSub { @@ -163,7 +164,7 @@ fn run_cursor(sp: MouseCursorService, state: &mut StateCursor) -> ResultType<()> lazy_static::lazy_static! { static ref ENIGO: Arc> = Arc::new(Mutex::new(Enigo::new())); - static ref KEYS_DOWN: Arc>> = Default::default(); + static ref KEYS_DOWN: Arc>> = Default::default(); static ref LATEST_INPUT: Arc> = Default::default(); } static EXITING: AtomicBool = AtomicBool::new(false); @@ -256,13 +257,15 @@ fn fix_key_down_timeout(force: bool) { if force || value.elapsed().as_millis() >= 3_000 { KEYS_DOWN.lock().unwrap().remove(&key); let key = if key < KEY_CHAR_START { - if let Some(key) = KEY_MAP.get(&key) { + if let Some(key) = KEY_MAP.get(&(key as _)) { Some(*key) } else { None } - } else { + } else if key < KEY_SYM_START { Some(Key::Layout(((key - KEY_CHAR_START) as u8) as _)) + } else { + Some(Key::KeySym((key - KEY_SYM_START) as u32)) }; if let Some(key) = key { let func = move || { @@ -352,7 +355,10 @@ fn handle_mouse_(evt: &MouseEvent, conn: i32) { modifier_sleep(); to_release.push(key); } else { - KEYS_DOWN.lock().unwrap().insert(ck.value(), Instant::now()); + KEYS_DOWN + .lock() + .unwrap() + .insert(ck.value() as _, Instant::now()); } } } @@ -572,7 +578,10 @@ fn handle_key_(evt: &KeyEvent) { modifier_sleep(); to_release.push(key); } else { - KEYS_DOWN.lock().unwrap().insert(ck.value(), Instant::now()); + KEYS_DOWN + .lock() + .unwrap() + .insert(ck.value() as _, Instant::now()); } } } @@ -606,10 +615,13 @@ fn handle_key_(evt: &KeyEvent) { } if evt.down { allow_err!(en.key_down(key.clone())); - KEYS_DOWN.lock().unwrap().insert(ck.value(), Instant::now()); + KEYS_DOWN + .lock() + .unwrap() + .insert(ck.value() as _, Instant::now()); } else { en.key_up(key.clone()); - KEYS_DOWN.lock().unwrap().remove(&ck.value()); + KEYS_DOWN.lock().unwrap().remove(&(ck.value() as _)); } } else if ck.value() == ControlKey::CtrlAltDel.value() { // have to spawn new thread because send_sas is tokio_main, the caller can not be tokio_main. @@ -627,13 +639,28 @@ fn handle_key_(evt: &KeyEvent) { KEYS_DOWN .lock() .unwrap() - .insert(chr as i32 + KEY_CHAR_START, Instant::now()); + .insert(chr as u64 + KEY_CHAR_START, Instant::now()); } else { en.key_up(Key::Layout(chr as u8 as _)); KEYS_DOWN .lock() .unwrap() - .remove(&(chr as i32 + KEY_CHAR_START)); + .remove(&(chr as u64 + KEY_CHAR_START)); + } + } + Some(key_event::Union::keysym(sym)) => { + if evt.down { + allow_err!(en.key_down(Key::KeySym(sym))); + KEYS_DOWN + .lock() + .unwrap() + .insert(sym as u64 + KEY_SYM_START, Instant::now()); + } else { + en.key_up(Key::KeySym(sym)); + KEYS_DOWN + .lock() + .unwrap() + .remove(&(sym as u64 + KEY_SYM_START)); } } Some(key_event::Union::unicode(chr)) => { diff --git a/src/ui/ab.tis b/src/ui/ab.tis index 22dc17f3d..84cfcef4f 100644 --- a/src/ui/ab.tis +++ b/src/ui/ab.tis @@ -95,7 +95,7 @@ class SessionList: Reactor.Component { function render() { var sessions = this.getSessions(); if (sessions.length == 0) { - return
{translate("Empty")}
; + return
{translate("Empty")}
; } var me = this; sessions = sessions.map(function(x) { return me.getSession(x); });