Remote side has a higher priority on mouse control
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
6bdb69f7bc
commit
60e8dd840f
@ -1,12 +1,8 @@
|
|||||||
use hbb_common::{
|
|
||||||
anyhow::{self, bail},
|
|
||||||
tokio, ResultType,
|
|
||||||
};
|
|
||||||
use reqwest::blocking::Response;
|
use reqwest::blocking::Response;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde_derive::Deserialize;
|
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
|
|
||||||
|
#[cfg(feature = "flutter")]
|
||||||
pub mod account;
|
pub mod account;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
use crate::common::IS_X11;
|
use crate::common::IS_X11;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use dispatch::Queue;
|
use dispatch::Queue;
|
||||||
@ -7,6 +8,7 @@ use hbb_common::{config::COMPRESS_LEVEL, get_time, protobuf::EnumOrUnknown};
|
|||||||
use rdev::{simulate, EventType, Key as RdevKey};
|
use rdev::{simulate, EventType, Key as RdevKey};
|
||||||
use std::{
|
use std::{
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
|
ops::Sub,
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
@ -100,8 +102,16 @@ pub fn new_pos() -> GenericService {
|
|||||||
sp
|
sp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_last_cursor_pos(x: i32, y: i32) {
|
||||||
|
let mut lock = LATEST_CURSOR_POS.lock().unwrap();
|
||||||
|
if lock.1 .0 != x || lock.1 .1 != y {
|
||||||
|
(lock.0, lock.1) = (Instant::now(), (x, y))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn run_pos(sp: GenericService, state: &mut StatePos) -> ResultType<()> {
|
fn run_pos(sp: GenericService, state: &mut StatePos) -> ResultType<()> {
|
||||||
if let Some((x, y)) = crate::get_cursor_pos() {
|
if let Some((x, y)) = crate::get_cursor_pos() {
|
||||||
|
update_last_cursor_pos(x, y);
|
||||||
if state.cursor_pos.0 != x || state.cursor_pos.1 != y {
|
if state.cursor_pos.0 != x || state.cursor_pos.1 != y {
|
||||||
state.cursor_pos = (x, y);
|
state.cursor_pos = (x, y);
|
||||||
let mut msg_out = Message::new();
|
let mut msg_out = Message::new();
|
||||||
@ -112,7 +122,7 @@ fn run_pos(sp: GenericService, state: &mut StatePos) -> ResultType<()> {
|
|||||||
});
|
});
|
||||||
let exclude = {
|
let exclude = {
|
||||||
let now = get_time();
|
let now = get_time();
|
||||||
let lock = LATEST_INPUT.lock().unwrap();
|
let lock = LATEST_INPUT_CURSOR.lock().unwrap();
|
||||||
if now - lock.time < 300 {
|
if now - lock.time < 300 {
|
||||||
lock.conn
|
lock.conn
|
||||||
} else {
|
} else {
|
||||||
@ -170,10 +180,15 @@ lazy_static::lazy_static! {
|
|||||||
Arc::new(Mutex::new(Enigo::new()))
|
Arc::new(Mutex::new(Enigo::new()))
|
||||||
};
|
};
|
||||||
static ref KEYS_DOWN: Arc<Mutex<HashMap<u64, Instant>>> = Default::default();
|
static ref KEYS_DOWN: Arc<Mutex<HashMap<u64, Instant>>> = Default::default();
|
||||||
static ref LATEST_INPUT: Arc<Mutex<Input>> = Default::default();
|
static ref LATEST_INPUT_CURSOR: Arc<Mutex<Input>> = Default::default();
|
||||||
|
static ref LATEST_INPUT_CURSOR_POS: Arc<Mutex<HashMap<i32, (i32, i32)>>> = Default::default();
|
||||||
|
static ref LATEST_CURSOR_POS: Arc<Mutex<(Instant, (i32, i32))>> = Arc::new(Mutex::new((Instant::now().sub(MOUSE_MOVE_PROTECTION_TIMEOUT), (0, 0))));
|
||||||
}
|
}
|
||||||
static EXITING: AtomicBool = AtomicBool::new(false);
|
static EXITING: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
|
const MOUSE_MOVE_PROTECTION_TIMEOUT: Duration = Duration::from_millis(1_000);
|
||||||
|
const MOUSE_ACTIVE_DISTANCE: i32 = 5;
|
||||||
|
|
||||||
// mac key input must be run in main thread, otherwise crash on >= osx 10.15
|
// mac key input must be run in main thread, otherwise crash on >= osx 10.15
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
@ -357,17 +372,43 @@ fn fix_modifiers(modifiers: &[EnumOrUnknown<ControlKey>], en: &mut Enigo, ck: i3
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_mouse_active_by_conn(conn: i32) -> bool {
|
||||||
|
if LATEST_CURSOR_POS.lock().unwrap().0.elapsed() > MOUSE_MOVE_PROTECTION_TIMEOUT {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
match LATEST_INPUT_CURSOR_POS.lock().unwrap().get(&conn) {
|
||||||
|
Some((x, y)) => match crate::get_cursor_pos() {
|
||||||
|
Some((x2, y2)) => {
|
||||||
|
(x - x2).abs() < MOUSE_ACTIVE_DISTANCE && (y - y2).abs() < MOUSE_ACTIVE_DISTANCE
|
||||||
|
}
|
||||||
|
None => true,
|
||||||
|
},
|
||||||
|
None => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_mouse_(evt: &MouseEvent, conn: i32) {
|
fn handle_mouse_(evt: &MouseEvent, conn: i32) {
|
||||||
if EXITING.load(Ordering::SeqCst) {
|
if EXITING.load(Ordering::SeqCst) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !is_mouse_active_by_conn(conn) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
crate::platform::windows::try_change_desktop();
|
crate::platform::windows::try_change_desktop();
|
||||||
let buttons = evt.mask >> 3;
|
let buttons = evt.mask >> 3;
|
||||||
let evt_type = evt.mask & 0x7;
|
let evt_type = evt.mask & 0x7;
|
||||||
if evt_type == 0 {
|
if evt_type == 0 {
|
||||||
let time = get_time();
|
let time = get_time();
|
||||||
*LATEST_INPUT.lock().unwrap() = Input { time, conn };
|
*LATEST_INPUT_CURSOR.lock().unwrap() = Input { time, conn };
|
||||||
|
|
||||||
|
LATEST_INPUT_CURSOR_POS
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.insert(conn, (evt.x, evt.y));
|
||||||
}
|
}
|
||||||
let mut en = ENIGO.lock().unwrap();
|
let mut en = ENIGO.lock().unwrap();
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
@ -432,7 +473,10 @@ fn handle_mouse_(evt: &MouseEvent, conn: i32) {
|
|||||||
|
|
||||||
// fix shift + scroll(down/up)
|
// fix shift + scroll(down/up)
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
if evt.modifiers.contains(&EnumOrUnknown::new(ControlKey::Shift)){
|
if evt
|
||||||
|
.modifiers
|
||||||
|
.contains(&EnumOrUnknown::new(ControlKey::Shift))
|
||||||
|
{
|
||||||
x = y;
|
x = y;
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
@ -653,16 +697,16 @@ fn sync_status(evt: &KeyEvent) -> (bool, bool) {
|
|||||||
let code = evt.chr();
|
let code = evt.chr();
|
||||||
let key = rdev::get_win_key(code, 0);
|
let key = rdev::get_win_key(code, 0);
|
||||||
match key {
|
match key {
|
||||||
RdevKey::Home |
|
RdevKey::Home
|
||||||
RdevKey::UpArrow |
|
| RdevKey::UpArrow
|
||||||
RdevKey::PageUp |
|
| RdevKey::PageUp
|
||||||
RdevKey::LeftArrow |
|
| RdevKey::LeftArrow
|
||||||
RdevKey::RightArrow |
|
| RdevKey::RightArrow
|
||||||
RdevKey::End |
|
| RdevKey::End
|
||||||
RdevKey::DownArrow |
|
| RdevKey::DownArrow
|
||||||
RdevKey::PageDown |
|
| RdevKey::PageDown
|
||||||
RdevKey::Insert |
|
| RdevKey::Insert
|
||||||
RdevKey::Delete => en.get_key_state(enigo::Key::NumLock),
|
| RdevKey::Delete => en.get_key_state(enigo::Key::NumLock),
|
||||||
_ => click_numlock,
|
_ => click_numlock,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
use hbb_common::log::{debug, error, info};
|
use hbb_common::log::debug;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use hbb_common::log::{error, info};
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use libappindicator::AppIndicator;
|
use libappindicator::AppIndicator;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
use std::env::temp_dir;
|
use std::env::temp_dir;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::{Arc, Mutex, RwLock},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use trayicon::{MenuBuilder, TrayIconBuilder};
|
use trayicon::{MenuBuilder, TrayIconBuilder};
|
||||||
|
@ -20,7 +20,9 @@ use hbb_common::{
|
|||||||
tokio::{self, sync::mpsc, time},
|
tokio::{self, sync::mpsc, time},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{common::SOFTWARE_UPDATE_URL, hbbs_http::account, ipc, platform};
|
use crate::{common::SOFTWARE_UPDATE_URL, ipc, platform};
|
||||||
|
#[cfg(feature = "flutter")]
|
||||||
|
use crate::hbbs_http::account;
|
||||||
|
|
||||||
type Message = RendezvousMessage;
|
type Message = RendezvousMessage;
|
||||||
|
|
||||||
@ -844,14 +846,17 @@ pub(crate) fn check_connect_status(reconnect: bool) -> mpsc::UnboundedSender<ipc
|
|||||||
tx
|
tx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "flutter")]
|
||||||
pub fn account_auth(op: String, id: String, uuid: String) {
|
pub fn account_auth(op: String, id: String, uuid: String) {
|
||||||
account::OidcSession::account_auth(op, id, uuid);
|
account::OidcSession::account_auth(op, id, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "flutter")]
|
||||||
pub fn account_auth_cancel() {
|
pub fn account_auth_cancel() {
|
||||||
account::OidcSession::auth_cancel();
|
account::OidcSession::auth_cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "flutter")]
|
||||||
pub fn account_auth_result() -> String {
|
pub fn account_auth_result() -> String {
|
||||||
serde_json::to_string(&account::OidcSession::get_result()).unwrap_or_default()
|
serde_json::to_string(&account::OidcSession::get_result()).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ use std::collections::{HashMap, HashSet};
|
|||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
/// IS_IN KEYBOARD_HOOKED sciter only
|
/// IS_IN KEYBOARD_HOOKED sciter only
|
||||||
pub static IS_IN: AtomicBool = AtomicBool::new(false);
|
pub static IS_IN: AtomicBool = AtomicBool::new(false);
|
||||||
@ -1323,7 +1322,7 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let func = move |event: Event| match event.event_type {
|
let func = move |event: Event| match event.event_type {
|
||||||
EventType::KeyPress(key) | EventType::KeyRelease(key) => {
|
EventType::KeyPress(..) | EventType::KeyRelease(..) => {
|
||||||
// grab all keys
|
// grab all keys
|
||||||
if !IS_IN.load(Ordering::SeqCst)
|
if !IS_IN.load(Ordering::SeqCst)
|
||||||
|| !SERVER_KEYBOARD_ENABLED.load(Ordering::SeqCst)
|
|| !SERVER_KEYBOARD_ENABLED.load(Ordering::SeqCst)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user