commit
e1344f5306
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -4305,7 +4305,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rdev"
|
name = "rdev"
|
||||||
version = "0.5.0-2"
|
version = "0.5.0-2"
|
||||||
source = "git+https://github.com/asur4s/rdev#3d6d413a9b2ab703edc22071acea31826b0efce3"
|
source = "git+https://github.com/asur4s/rdev#18bb9dd64563fc9761005bb39ff830e6402e326e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cocoa",
|
"cocoa",
|
||||||
"core-foundation 0.9.3",
|
"core-foundation 0.9.3",
|
||||||
@ -4316,6 +4316,7 @@ dependencies = [
|
|||||||
"inotify",
|
"inotify",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
|
"log",
|
||||||
"mio 0.8.5",
|
"mio 0.8.5",
|
||||||
"strum 0.24.1",
|
"strum 0.24.1",
|
||||||
"strum_macros 0.24.3",
|
"strum_macros 0.24.3",
|
||||||
|
@ -7,19 +7,19 @@ use crate::flutter::FlutterHandler;
|
|||||||
use crate::ui::remote::SciterHandler;
|
use crate::ui::remote::SciterHandler;
|
||||||
use crate::ui_session_interface::Session;
|
use crate::ui_session_interface::Session;
|
||||||
use hbb_common::{log, message_proto::*};
|
use hbb_common::{log, message_proto::*};
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
use rdev::GrabError;
|
|
||||||
use rdev::{Event, EventType, Key};
|
use rdev::{Event, EventType, Key};
|
||||||
|
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
sync::{
|
sync::{Arc, Mutex},
|
||||||
atomic::{AtomicBool, Ordering},
|
|
||||||
Arc, Mutex,
|
|
||||||
},
|
|
||||||
time::SystemTime,
|
time::SystemTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
static mut IS_ALT_GR: bool = false;
|
static mut IS_ALT_GR: bool = false;
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
||||||
static KEYBOARD_HOOKED: AtomicBool = AtomicBool::new(false);
|
static KEYBOARD_HOOKED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
#[cfg(feature = "flutter")]
|
#[cfg(feature = "flutter")]
|
||||||
@ -103,9 +103,10 @@ pub mod client {
|
|||||||
if is_long_press(&event) {
|
if is_long_press(&event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let key_event = event_to_key_event(&event);
|
if let Some(key_event) = event_to_key_event(&event) {
|
||||||
send_key_event(&key_event);
|
send_key_event(&key_event);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_modifiers_state(
|
pub fn get_modifiers_state(
|
||||||
alt: bool,
|
alt: bool,
|
||||||
@ -314,7 +315,7 @@ fn update_modifiers_state(event: &Event) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn event_to_key_event(event: &Event) -> KeyEvent {
|
pub fn event_to_key_event(event: &Event) -> Option<KeyEvent> {
|
||||||
let mut key_event = KeyEvent::new();
|
let mut key_event = KeyEvent::new();
|
||||||
update_modifiers_state(event);
|
update_modifiers_state(event);
|
||||||
|
|
||||||
@ -330,22 +331,22 @@ pub fn event_to_key_event(event: &Event) -> KeyEvent {
|
|||||||
|
|
||||||
let keyboard_mode = get_keyboard_mode_enum();
|
let keyboard_mode = get_keyboard_mode_enum();
|
||||||
key_event.mode = keyboard_mode.into();
|
key_event.mode = keyboard_mode.into();
|
||||||
match keyboard_mode {
|
let mut key_event = match keyboard_mode {
|
||||||
KeyboardMode::Map => {
|
KeyboardMode::Map => {
|
||||||
map_keyboard_mode(event, &mut key_event);
|
map_keyboard_mode(event, key_event)?
|
||||||
}
|
}
|
||||||
KeyboardMode::Translate => {
|
KeyboardMode::Translate => {
|
||||||
translate_keyboard_mode(event, &mut key_event);
|
translate_keyboard_mode(event, key_event)?
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
legacy_keyboard_mode(event, &mut key_event);
|
legacy_keyboard_mode(event, key_event)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
add_numlock_capslock_status(&mut key_event);
|
add_numlock_capslock_status(&mut key_event);
|
||||||
|
|
||||||
return key_event;
|
return Some(key_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn event_type_to_event(event_type: EventType) -> Event {
|
pub fn event_type_to_event(event_type: EventType) -> Event {
|
||||||
@ -374,13 +375,13 @@ pub fn get_peer_platform() -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub fn legacy_keyboard_mode(event: &Event, key_event: &mut KeyEvent) {
|
pub fn legacy_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option<KeyEvent> {
|
||||||
// legacy mode(0): Generate characters locally, look for keycode on other side.
|
// legacy mode(0): Generate characters locally, look for keycode on other side.
|
||||||
let (mut key, down_or_up) = match event.event_type {
|
let (mut key, down_or_up) = match event.event_type {
|
||||||
EventType::KeyPress(key) => (key, true),
|
EventType::KeyPress(key) => (key, true),
|
||||||
EventType::KeyRelease(key) => (key, false),
|
EventType::KeyRelease(key) => (key, false),
|
||||||
_ => {
|
_ => {
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -422,11 +423,11 @@ pub fn legacy_keyboard_mode(event: &Event, key_event: &mut KeyEvent) {
|
|||||||
// when pressing AltGr, an extra VK_LCONTROL with a special
|
// when pressing AltGr, an extra VK_LCONTROL with a special
|
||||||
// scancode with bit 9 set is sent, let's ignore this.
|
// scancode with bit 9 set is sent, let's ignore this.
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
if event.scan_code & 0x200 != 0 {
|
if (event.scan_code >> 8) == 0xE0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
IS_ALT_GR = true;
|
IS_ALT_GR = true;
|
||||||
}
|
}
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
Some(ControlKey::Control)
|
Some(ControlKey::Control)
|
||||||
}
|
}
|
||||||
@ -458,7 +459,7 @@ pub fn legacy_keyboard_mode(event: &Event, key_event: &mut KeyEvent) {
|
|||||||
Key::Delete => {
|
Key::Delete => {
|
||||||
if is_win && ctrl && alt {
|
if is_win && ctrl && alt {
|
||||||
client::ctrl_alt_del();
|
client::ctrl_alt_del();
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
Some(ControlKey::Delete)
|
Some(ControlKey::Delete)
|
||||||
}
|
}
|
||||||
@ -496,7 +497,7 @@ pub fn legacy_keyboard_mode(event: &Event, key_event: &mut KeyEvent) {
|
|||||||
Key::KpMinus => Some(ControlKey::Subtract),
|
Key::KpMinus => Some(ControlKey::Subtract),
|
||||||
Key::KpPlus => Some(ControlKey::Add),
|
Key::KpPlus => Some(ControlKey::Add),
|
||||||
Key::CapsLock | Key::NumLock | Key::ScrollLock => {
|
Key::CapsLock | Key::NumLock | Key::ScrollLock => {
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
Key::Home => Some(ControlKey::Home),
|
Key::Home => Some(ControlKey::Home),
|
||||||
Key::End => Some(ControlKey::End),
|
Key::End => Some(ControlKey::End),
|
||||||
@ -579,43 +580,60 @@ pub fn legacy_keyboard_mode(event: &Event, key_event: &mut KeyEvent) {
|
|||||||
if chr != '\0' {
|
if chr != '\0' {
|
||||||
if chr == 'l' && is_win && command {
|
if chr == 'l' && is_win && command {
|
||||||
client::lock_screen();
|
client::lock_screen();
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
key_event.set_chr(chr as _);
|
key_event.set_chr(chr as _);
|
||||||
} else {
|
} else {
|
||||||
log::error!("Unknown key {:?}", &event);
|
log::error!("Unknown key {:?}", &event);
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let (alt, ctrl, shift, command) = client::get_modifiers_state(alt, ctrl, shift, command);
|
let (alt, ctrl, shift, command) = client::get_modifiers_state(alt, ctrl, shift, command);
|
||||||
client::legacy_modifiers(key_event, alt, ctrl, shift, command);
|
client::legacy_modifiers(&mut key_event, alt, ctrl, shift, command);
|
||||||
|
|
||||||
if down_or_up == true {
|
if down_or_up == true {
|
||||||
key_event.down = true;
|
key_event.down = true;
|
||||||
}
|
}
|
||||||
|
Some(key_event)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_keyboard_mode(event: &Event, key_event: &mut KeyEvent) {
|
pub fn map_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option<KeyEvent> {
|
||||||
|
match event.event_type {
|
||||||
|
EventType::KeyPress(..) => {
|
||||||
|
key_event.down = true;
|
||||||
|
}
|
||||||
|
EventType::KeyRelease(..) => {
|
||||||
|
key_event.down = false;
|
||||||
|
}
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
let mut peer = get_peer_platform().to_lowercase();
|
let mut peer = get_peer_platform().to_lowercase();
|
||||||
peer.retain(|c| !c.is_whitespace());
|
peer.retain(|c| !c.is_whitespace());
|
||||||
|
|
||||||
let key = match event.event_type {
|
#[cfg(target_os = "windows")]
|
||||||
EventType::KeyPress(key) => {
|
let keycode = match peer.as_str() {
|
||||||
key_event.down = true;
|
"windows" => event.scan_code,
|
||||||
key
|
"macos" => rdev::win_scancode_to_macos_code(event.scan_code)?,
|
||||||
}
|
_ => rdev::win_scancode_to_linux_code(event.scan_code)?,
|
||||||
EventType::KeyRelease(key) => {
|
|
||||||
key_event.down = false;
|
|
||||||
key
|
|
||||||
}
|
|
||||||
_ => return,
|
|
||||||
};
|
};
|
||||||
let keycode: u32 = match peer.as_str() {
|
#[cfg(target_os = "macos")]
|
||||||
"windows" => rdev::win_keycode_from_key(key).unwrap_or_default().into(),
|
let keycode = match peer.as_str() {
|
||||||
"macos" => rdev::macos_keycode_from_key(key).unwrap_or_default().into(),
|
"windows" => rdev::macos_code_to_win_scancode(event.code as _)?,
|
||||||
_ => rdev::linux_keycode_from_key(key).unwrap_or_default().into(),
|
"macos" => event.code as _,
|
||||||
|
_ => rdev::macos_code_to_linux_code(event.code as _)?,
|
||||||
};
|
};
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
let keycode = match peer.as_str() {
|
||||||
|
"windows" => rdev::linux_code_to_win_scancode(event.code as _)?,
|
||||||
|
"macos" => rdev::linux_code_to_macos_code(event.code as _)?,
|
||||||
|
_ => event.code as _,
|
||||||
|
};
|
||||||
|
|
||||||
key_event.set_chr(keycode);
|
key_event.set_chr(keycode);
|
||||||
|
Some(key_event)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn translate_keyboard_mode(_event: &Event, _key_event: &mut KeyEvent) {}
|
pub fn translate_keyboard_mode(_event: &Event, mut _key_event: KeyEvent) -> Option<KeyEvent> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@ use crate::common::IS_X11;
|
|||||||
use dispatch::Queue;
|
use dispatch::Queue;
|
||||||
use enigo::{Enigo, Key, KeyboardControllable, MouseButton, MouseControllable};
|
use enigo::{Enigo, Key, KeyboardControllable, MouseButton, MouseControllable};
|
||||||
use hbb_common::{config::COMPRESS_LEVEL, get_time, protobuf::EnumOrUnknown};
|
use hbb_common::{config::COMPRESS_LEVEL, get_time, protobuf::EnumOrUnknown};
|
||||||
use rdev::{simulate, EventType, Key as RdevKey};
|
use rdev::{self, simulate, EventType, Key as RdevKey, RawKey};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{
|
use std::{
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
@ -686,6 +686,20 @@ pub fn handle_key(evt: &KeyEvent) {
|
|||||||
handle_key_(evt);
|
handle_key_(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sim_rdev_rawkey(code: u32, down_or_up: bool) {
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
let rawkey = RawKey::ScanCode(code);
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
let rawkey = RawKey::LinuxXorgKeycode(code);
|
||||||
|
// // to-do: test android
|
||||||
|
// #[cfg(target_os = "android")]
|
||||||
|
// let rawkey = RawKey::LinuxConsoleKeycode(code);
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
let rawkey = RawKey::MacVirtualKeycode(code);
|
||||||
|
|
||||||
|
rdev_key_down_or_up(RdevKey::RawKey(rawkey), down_or_up);
|
||||||
|
}
|
||||||
|
|
||||||
fn rdev_key_down_or_up(key: RdevKey, down_or_up: bool) {
|
fn rdev_key_down_or_up(key: RdevKey, down_or_up: bool) {
|
||||||
let event_type = match down_or_up {
|
let event_type = match down_or_up {
|
||||||
true => EventType::KeyPress(key),
|
true => EventType::KeyPress(key),
|
||||||
@ -821,8 +835,7 @@ fn map_keyboard_mode(evt: &KeyEvent) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdev_key_down_or_up(RdevKey::Unknown(evt.chr()), evt.down);
|
sim_rdev_rawkey(evt.chr(), evt.down);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
@ -850,6 +863,7 @@ fn release_unpressed_modifiers(en: &mut Enigo, key_event: &KeyEvent) {
|
|||||||
fix_modifiers(&key_event.modifiers[..], en, ck_value);
|
fix_modifiers(&key_event.modifiers[..], en, ck_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
fn is_altgr_pressed() -> bool {
|
fn is_altgr_pressed() -> bool {
|
||||||
KEYS_DOWN
|
KEYS_DOWN
|
||||||
.lock()
|
.lock()
|
||||||
|
@ -13,7 +13,6 @@ use objc::{
|
|||||||
};
|
};
|
||||||
use sciter::{make_args, Host};
|
use sciter::{make_args, Host};
|
||||||
use std::{ffi::c_void, rc::Rc};
|
use std::{ffi::c_void, rc::Rc};
|
||||||
use dark_light;
|
|
||||||
|
|
||||||
static APP_HANDLER_IVAR: &str = "GoDeskAppHandler";
|
static APP_HANDLER_IVAR: &str = "GoDeskAppHandler";
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
let scancode: u32 = scancode as u32;
|
let scancode: u32 = scancode as u32;
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
let key = rdev::key_from_scancode(scancode) as rdev::Key;
|
let key = rdev::key_from_code(keycode) as rdev::Key;
|
||||||
// Windows requires special handling
|
// Windows requires special handling
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let key = rdev::get_win_key(keycode, scancode);
|
let key = rdev::get_win_key(keycode, scancode);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user