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