macos_accessibility_client/
lib.rs

1#![allow(non_snake_case)]
2
3/// Raw C-bindings for some of Apple's accessibility API. See [Apple's documentation](https://developer.apple.com/documentation/applicationservices/axuielement_h?language=objc#overview)
4pub mod raw {
5    use core_foundation::string::CFStringRef;
6    use core_foundation_sys::base::Boolean;
7    use core_foundation_sys::dictionary::CFDictionaryRef;
8
9    unsafe extern "C" {
10        pub static kAXTrustedCheckOptionPrompt: CFStringRef;
11
12        pub fn AXIsProcessTrusted() -> Boolean;
13        pub fn AXIsProcessTrustedWithOptions(theDict: CFDictionaryRef) -> Boolean;
14
15    }
16}
17
18/// Wrapped bindings to some of Apple's accessibility client API.
19pub mod accessibility {
20    use core_foundation::base::TCFType;
21    use core_foundation::boolean::CFBoolean;
22    use core_foundation::dictionary::CFDictionary;
23    use core_foundation::string::CFString;
24
25    use crate::raw::{
26        kAXTrustedCheckOptionPrompt, AXIsProcessTrusted, AXIsProcessTrustedWithOptions,
27    };
28
29    /// Checks whether or not this application is a trusted accessibility client.
30    pub fn application_is_trusted() -> bool {
31        unsafe {
32            return AXIsProcessTrusted() != 0;
33        }
34    }
35
36    /// Same as [application_is_trusted], but also shows the user a prompt asking
37    /// them to allow accessibility API access if it hasn't already been given.
38    pub fn application_is_trusted_with_prompt() -> bool {
39        unsafe {
40            let option_prompt = CFString::wrap_under_get_rule(kAXTrustedCheckOptionPrompt);
41            let dict: CFDictionary<CFString, CFBoolean> =
42                CFDictionary::from_CFType_pairs(&[(option_prompt, CFBoolean::true_value())]);
43            return AXIsProcessTrustedWithOptions(dict.as_concrete_TypeRef()) != 0;
44        }
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use crate::accessibility::{application_is_trusted, application_is_trusted_with_prompt};
51
52    #[test]
53    fn test_application_is_trusted() {
54        assert_eq!(false, application_is_trusted());
55    }
56
57    #[test]
58    fn test_application_is_trusted_with_prompt() {
59        assert_eq!(false, application_is_trusted_with_prompt());
60    }
61}