diff --git a/build.rs b/build.rs index 67e40752c..ade63f0bc 100644 --- a/build.rs +++ b/build.rs @@ -1,9 +1,16 @@ #[cfg(windows)] fn build_windows() { - cc::Build::new().file("src/windows.cc").compile("windows"); + let file = "src/platform/windows.cc"; + cc::Build::new().file(file).compile("windows"); println!("cargo:rustc-link-lib=WtsApi32"); - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=windows.cc"); + println!("cargo:rerun-if-changed={}", file); +} + +#[cfg(target_os = "macos")] +fn build_mac() { + let file = "src/platform/macos.mm"; + cc::Build::new().file(file).compile("macos"); + println!("cargo:rerun-if-changed={}", file); } #[cfg(all(windows, feature = "inline"))] @@ -117,5 +124,8 @@ fn main() { #[cfg(windows)] build_windows(); #[cfg(target_os = "macos")] + build_mac(); + #[cfg(target_os = "macos")] println!("cargo:rustc-link-lib=framework=ApplicationServices"); + println!("cargo:rerun-if-changed=build.rs"); } diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 25161e1e3..92f1e0606 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -1113,6 +1113,10 @@ pub fn main_is_can_screen_recording(prompt: bool) -> SyncReturn { SyncReturn(is_can_screen_recording(prompt)) } +pub fn main_is_can_input_monitoring(prompt: bool) -> SyncReturn { + SyncReturn(is_can_input_monitoring(prompt)) +} + pub fn main_is_share_rdp() -> SyncReturn { SyncReturn(is_share_rdp()) } diff --git a/src/platform/macos.mm b/src/platform/macos.mm new file mode 100644 index 000000000..b82b269e2 --- /dev/null +++ b/src/platform/macos.mm @@ -0,0 +1,34 @@ +#import +#import +#import + +extern "C" bool InputMonitoringAuthStatus(bool prompt) { + if (@available(macos 10.15, *)) { + IOHIDAccessType theType = IOHIDCheckAccess(kIOHIDRequestTypeListenEvent); + NSLog(@"IOHIDCheckAccess = %d", theType); + switch (theType) { + case kIOHIDAccessTypeGranted: + return true; + break; + case kIOHIDAccessTypeDenied: { + if (prompt) { + NSString *urlString = @"x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent"; + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]]; + } + break; + } + case kIOHIDAccessTypeUnknown: { + if (prompt) { + bool result = IOHIDRequestAccess(kIOHIDRequestTypeListenEvent); + NSLog(@"IOHIDRequestAccess result = %d", result); + } + break; + } + default: + break; + } + } else { + return true; + } + return false; +} diff --git a/src/platform/macos.rs b/src/platform/macos.rs index 0bbec399c..62fa1ee25 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -32,6 +32,7 @@ extern "C" { fn CGEventGetLocation(e: *const c_void) -> CGPoint; static kAXTrustedCheckOptionPrompt: CFStringRef; fn AXIsProcessTrustedWithOptions(options: CFDictionaryRef) -> BOOL; + fn InputMonitoringAuthStatus(_: BOOL) -> BOOL; } pub fn is_process_trusted(prompt: bool) -> bool { @@ -47,6 +48,13 @@ pub fn is_process_trusted(prompt: bool) -> bool { } } +pub fn is_can_input_monitoring(prompt: bool) -> bool { + unsafe { + let value = if prompt { YES } else { NO }; + InputMonitoringAuthStatus(value) == YES + } +} + // macOS >= 10.15 // https://stackoverflow.com/questions/56597221/detecting-screen-recording-settings-on-macos-catalina/ // remove just one app from all the permissions: tccutil reset All com.carriez.rustdesk diff --git a/src/windows.cc b/src/platform/windows.cc similarity index 100% rename from src/windows.cc rename to src/platform/windows.cc diff --git a/src/ui_interface.rs b/src/ui_interface.rs index 2e4ca4ea3..3b7d1c2c0 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -582,6 +582,14 @@ pub fn is_installed_daemon(_prompt: bool) -> bool { return true; } +#[inline] +pub fn is_can_input_monitoring(_prompt: bool) -> bool { + #[cfg(target_os = "macos")] + return crate::platform::macos::is_can_input_monitoring(_prompt); + #[cfg(not(target_os = "macos"))] + return true; +} + #[inline] pub fn get_error() -> String { #[cfg(not(any(feature = "cli")))]