mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-14 00:11:01 +03:00
Keep one macOS cursor density snapshot and retry failed captures
This commit is contained in:
@@ -37,6 +37,9 @@ use std::{
|
||||
|
||||
mod cursor;
|
||||
|
||||
#[cfg(test)]
|
||||
mod cursor_poll_tests;
|
||||
|
||||
// macOS boolean_t is defined as `int` in <mach/boolean.h>
|
||||
type BooleanT = hbb_common::libc::c_int;
|
||||
|
||||
@@ -567,10 +570,10 @@ fn unsafe_get_cursor() -> ResultType<Option<u64>> {
|
||||
if seed == LATEST_SEED {
|
||||
return Ok(None);
|
||||
}
|
||||
let c = get_cursor_id(seed.1)?;
|
||||
LATEST_SEED = seed;
|
||||
Ok(Some(c.1))
|
||||
}
|
||||
let c = get_cursor_id()?;
|
||||
Ok(Some(c.1))
|
||||
}
|
||||
|
||||
pub fn reset_input_cache() {
|
||||
@@ -579,7 +582,7 @@ pub fn reset_input_cache() {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_cursor_id() -> ResultType<(id, u64, f64)> {
|
||||
fn get_cursor_id(scale: f64) -> ResultType<(id, u64)> {
|
||||
unsafe {
|
||||
let c: id = msg_send![class!(NSCursor), currentSystemCursor];
|
||||
if c == nil {
|
||||
@@ -622,19 +625,25 @@ fn get_cursor_id() -> ResultType<(id, u64, f64)> {
|
||||
hcursor += (r + g + b + a) * (255 << i) as f64;
|
||||
}
|
||||
}
|
||||
let scale = cursor::scale()?;
|
||||
Ok((c, cursor::cache_id(hcursor as _, scale), scale))
|
||||
Ok((c, cursor::cache_id(hcursor as _, scale)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cursor_data(hcursor: u64) -> ResultType<CursorData> {
|
||||
autoreleasepool(|| unsafe_get_cursor_data(hcursor))
|
||||
let result = autoreleasepool(|| unsafe_get_cursor_data(hcursor));
|
||||
if result.is_err() {
|
||||
// A failed capture must be retried even if the seed and density stay unchanged.
|
||||
reset_input_cache();
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
// https://github.com/stweil/OSXvnc/blob/master/OSXvnc-server/mousecursor.c
|
||||
fn unsafe_get_cursor_data(hcursor: u64) -> ResultType<CursorData> {
|
||||
unsafe {
|
||||
let (c, hcursor2, scale) = get_cursor_id()?;
|
||||
// Keep the poll's density if the pointer crosses displays before capture.
|
||||
let scale = LATEST_SEED.1;
|
||||
let (c, hcursor2) = get_cursor_id(scale)?;
|
||||
if hcursor != hcursor2 {
|
||||
bail!("cursor changed");
|
||||
}
|
||||
|
||||
17
src/platform/macos/cursor_poll_tests.rs
Normal file
17
src/platform/macos/cursor_poll_tests.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn capture_failure_invalidates_the_density_poll() {
|
||||
let previous = unsafe { LATEST_SEED };
|
||||
unsafe {
|
||||
LATEST_SEED = (1, 2.0);
|
||||
}
|
||||
// Zero cannot be a macOS cursor ID, even if AppKit has no current cursor.
|
||||
let result = get_cursor_data(0);
|
||||
let after_failure = unsafe { LATEST_SEED };
|
||||
unsafe {
|
||||
LATEST_SEED = previous;
|
||||
}
|
||||
assert!(result.is_err());
|
||||
assert_eq!(after_failure, (0, 0.0));
|
||||
}
|
||||
Reference in New Issue
Block a user