fix cursor move on macOS

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2023-05-04 14:38:04 +08:00
parent 0ed209b4d2
commit 477cbff489

View File

@ -510,27 +510,17 @@ pub fn handle_mouse(evt: &MouseEvent, conn: i32) {
if !active_mouse_(conn) { if !active_mouse_(conn) {
return; return;
} }
let evt_type = evt.mask & 0x7;
if evt_type == 0 {
let time = get_time();
*LATEST_PEER_INPUT_CURSOR.lock().unwrap() = Input {
time,
conn,
x: evt.x,
y: evt.y,
};
}
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
if !is_server() { if !is_server() {
// having GUI, run main GUI thread, otherwise crash // having GUI, run main GUI thread, otherwise crash
let evt = evt.clone(); let evt = evt.clone();
QUEUE.exec_async(move || handle_mouse_(&evt)); QUEUE.exec_async(move || handle_mouse_(&evt, conn));
return; return;
} }
#[cfg(windows)] #[cfg(windows)]
crate::portable_service::client::handle_mouse(evt); crate::portable_service::client::handle_mouse(evt);
#[cfg(not(windows))] #[cfg(not(windows))]
handle_mouse_(evt); handle_mouse_(evt, conn);
} }
pub fn fix_key_down_timeout_loop() { pub fn fix_key_down_timeout_loop() {
@ -683,6 +673,12 @@ fn fix_modifiers(modifiers: &[EnumOrUnknown<ControlKey>], en: &mut Enigo, ck: i3
} }
} }
#[inline]
fn get_last_input_cusor_pos() -> (i32, i32) {
let lock = LATEST_PEER_INPUT_CURSOR.lock().unwrap();
(lock.x, lock.y)
}
fn active_mouse_(conn: i32) -> bool { fn active_mouse_(conn: i32) -> bool {
// out of time protection // out of time protection
if LATEST_SYS_CURSOR_POS.lock().unwrap().0.elapsed() > MOUSE_MOVE_PROTECTION_TIMEOUT { if LATEST_SYS_CURSOR_POS.lock().unwrap().0.elapsed() > MOUSE_MOVE_PROTECTION_TIMEOUT {
@ -699,20 +695,32 @@ fn active_mouse_(conn: i32) -> bool {
// Check if input is in valid range // Check if input is in valid range
match crate::get_cursor_pos() { match crate::get_cursor_pos() {
Some((x, y)) => { Some((x, y)) => {
let (last_in_x, last_in_y) = { let (last_in_x, last_in_y) = get_last_input_cusor_pos();
let lock = LATEST_PEER_INPUT_CURSOR.lock().unwrap();
(lock.x, lock.y)
};
let mut can_active = in_active_dist(last_in_x, x) && in_active_dist(last_in_y, y); let mut can_active = in_active_dist(last_in_x, x) && in_active_dist(last_in_y, y);
// The cursor may not have been moved to last input position if system is busy now. // The cursor may not have been moved to last input position if system is busy now.
// While this is not a common case, we check it again after some time later. // While this is not a common case, we check it again after some time later.
if !can_active { if !can_active {
// 10 micros may be enough for system to move cursor. // 100 micros may be enough for system to move cursor.
// We do not care about the situation which system is too slow(more than 10 micros is required). // Mouse inputs on macOS are asynchronous. 1. Put in a queue to process in main thread. 2. Send event async.
std::thread::sleep(std::time::Duration::from_micros(10)); // More reties are needed on macOS.
// Sleep here can also somehow suppress delay accumulation. #[cfg(not(target_os = "macos"))]
if let Some((x2, y2)) = crate::get_cursor_pos() { let retries = 10;
can_active = in_active_dist(last_in_x, x2) && in_active_dist(last_in_y, y2); #[cfg(target_os = "macos")]
let retries = 100;
#[cfg(not(target_os = "macos"))]
let sleep_interval: u64 = 10;
#[cfg(target_os = "macos")]
let sleep_interval: u64 = 30;
for _retry in 0..retries {
std::thread::sleep(std::time::Duration::from_micros(sleep_interval));
// Sleep here can also somehow suppress delay accumulation.
if let Some((x2, y2)) = crate::get_cursor_pos() {
let (last_in_x, last_in_y) = get_last_input_cusor_pos();
can_active = in_active_dist(last_in_x, x2) && in_active_dist(last_in_y, y2);
if can_active {
break;
}
}
} }
} }
if !can_active { if !can_active {
@ -726,7 +734,7 @@ fn active_mouse_(conn: i32) -> bool {
} }
} }
pub fn handle_mouse_(evt: &MouseEvent) { pub fn handle_mouse_(evt: &MouseEvent, conn: i32) {
if EXITING.load(Ordering::SeqCst) { if EXITING.load(Ordering::SeqCst) {
return; return;
} }
@ -761,6 +769,12 @@ pub fn handle_mouse_(evt: &MouseEvent) {
match evt_type { match evt_type {
0 => { 0 => {
en.mouse_move_to(evt.x, evt.y); en.mouse_move_to(evt.x, evt.y);
*LATEST_PEER_INPUT_CURSOR.lock().unwrap() = Input {
time: get_time(),
conn,
x: evt.x,
y: evt.y,
};
} }
1 => match buttons { 1 => match buttons {
0x01 => { 0x01 => {