accessibility_ng/
attribute.rs

1use accessibility_sys_ng::{
2    kAXAXNextLineRangeForIndexParameterizedAttribute,
3    kAXAXPreviousLineRangeForIndexParameterizedAttribute, kAXAllowedValuesAttribute,
4    kAXAttributedStringForRangeParameterizedAttribute, kAXBoundsForRangeParameterizedAttribute,
5    kAXChildrenAttribute, kAXContentsAttribute, kAXDescriptionAttribute, kAXDocumentAttribute,
6    kAXElementBusyAttribute, kAXEnabledAttribute, kAXFocusedApplicationAttribute,
7    kAXFocusedAttribute, kAXFocusedUIElementAttribute, kAXFocusedWindowAttribute,
8    kAXFrameAttribute, kAXFrontmostAttribute, kAXHelpAttribute, kAXIdentifierAttribute,
9    kAXLabelValueAttribute, kAXLineForIndexParameterizedAttribute, kAXMainAttribute,
10    kAXMainWindowAttribute, kAXMaxValueAttribute, kAXMenuItemCmdCharAttribute,
11    kAXMenuItemCmdGlyphAttribute, kAXMenuItemCmdModifiersAttribute,
12    kAXMenuItemCmdVirtualKeyAttribute, kAXMenuItemMarkCharAttribute, kAXMinValueAttribute,
13    kAXMinimizedAttribute, kAXNumberOfCharactersAttribute, kAXParentAttribute,
14    kAXPlaceholderValueAttribute, kAXPositionAttribute, kAXRangeForLineParameterizedAttribute,
15    kAXRangeForPositionParameterizedAttribute, kAXRoleAttribute, kAXRoleDescriptionAttribute,
16    kAXSelectedChildrenAttribute, kAXSelectedTextAttribute, kAXSelectedTextRangeAttribute,
17    kAXSizeAttribute, kAXSubroleAttribute, kAXTitleAttribute, kAXTopLevelUIElementAttribute,
18    kAXValueAttribute, kAXValueDescriptionAttribute, kAXValueIncrementAttribute,
19    kAXVisibleCharacterRangeAttribute, kAXVisibleChildrenAttribute, kAXWindowAttribute,
20    kAXWindowsAttribute,
21};
22use core_foundation::{
23    array::CFArray,
24    attributed_string::CFAttributedString,
25    base::{CFType, TCFType},
26    boolean::CFBoolean,
27    number::CFNumber,
28    string::CFString,
29};
30use std::marker::PhantomData;
31
32use crate::{AXUIElement, AXValue, ElementFinder, Error};
33
34pub trait TAXAttribute {
35    type Value: TCFType;
36}
37
38#[derive(Clone, Debug)]
39pub struct AXAttribute<T>(CFString, PhantomData<*const T>);
40
41impl<T: TCFType> TAXAttribute for AXAttribute<T> {
42    type Value = T;
43}
44
45impl<T> AXAttribute<T> {
46    #[allow(non_snake_case)]
47    pub fn as_CFString(&self) -> &CFString {
48        &self.0
49    }
50}
51
52macro_rules! accessor {
53    (@decl $name:ident, $typ:ty, $const:ident, $setter:ident) => {
54        accessor!(@decl $name, $typ, $const);
55        fn $setter(&self, value: impl Into<$typ>) -> Result<(), Error>;
56    };
57    (@decl $name:ident, $typ:ty, $const:ident) => {
58        fn $name(&self) -> Result<$typ, Error>;
59    };
60    (@impl $name:ident, $typ:ty, $const:ident, $setter:ident) => {
61        accessor!(@impl $name, $typ, $const);
62        fn $setter(&self, value: impl Into<$typ>) -> Result<(), Error> {
63            self.set_attribute(&AXAttribute::$name(), value)
64        }
65    };
66    (@impl $name:ident, $typ:ty, $const:ident) => {
67        fn $name(&self) -> Result<$typ, Error> {
68            self.attribute(&AXAttribute::$name())
69        }
70    };
71}
72
73macro_rules! define_attributes {
74    ($(($name:ident, $typ:ty, $const:ident $(,$setter:ident)?)),*,) => {
75        impl AXAttribute<()> {
76            $(
77                pub fn $name() -> AXAttribute<$typ> {
78                    AXAttribute(CFString::from_static_string($const), PhantomData)
79                }
80            )*
81        }
82
83        pub trait AXUIElementAttributes {
84            $(accessor!(@decl $name, $typ, $const $(, $setter)? );)*
85        }
86
87        impl AXUIElementAttributes for AXUIElement {
88            $(accessor!(@impl $name, $typ, $const $(, $setter)? );)*
89        }
90
91        impl AXUIElementAttributes for ElementFinder {
92            $(accessor!(@impl $name, $typ, $const $(, $setter)? );)*
93        }
94    }
95}
96
97impl AXAttribute<CFType> {
98    pub fn new(name: &CFString) -> Self {
99        AXAttribute(name.to_owned(), PhantomData)
100    }
101}
102
103define_attributes![
104    (allowed_values, CFArray<CFType>, kAXAllowedValuesAttribute),
105    (children, CFArray<AXUIElement>, kAXChildrenAttribute),
106    (contents, AXUIElement, kAXContentsAttribute),
107    (description, CFString, kAXDescriptionAttribute),
108    (document, CFString, kAXDocumentAttribute),
109    (element_busy, CFBoolean, kAXElementBusyAttribute),
110    (enabled, CFBoolean, kAXEnabledAttribute),
111    (
112        focused_application,
113        AXUIElement,
114        kAXFocusedApplicationAttribute
115    ),
116    (focused_uielement, AXUIElement, kAXFocusedUIElementAttribute),
117    (focused, CFBoolean, kAXFocusedAttribute),
118    (focused_window, AXUIElement, kAXFocusedWindowAttribute),
119    (frontmost, CFBoolean, kAXFrontmostAttribute, set_frontmost),
120    (frame, AXValue, kAXFrameAttribute),
121    (help, CFString, kAXHelpAttribute),
122    (identifier, CFString, kAXIdentifierAttribute),
123    (label_value, CFString, kAXLabelValueAttribute),
124    (main, CFBoolean, kAXMainAttribute, set_main),
125    (main_window, AXUIElement, kAXMainWindowAttribute),
126    (max_value, CFType, kAXMaxValueAttribute),
127    (
128        menu_item_cmd_modifier,
129        CFNumber,
130        kAXMenuItemCmdModifiersAttribute
131    ),
132    (menu_item_cmd_char, CFString, kAXMenuItemCmdCharAttribute),
133    (
134        menu_item_cmd_virtual_key,
135        CFString,
136        kAXMenuItemCmdVirtualKeyAttribute
137    ),
138    (menu_item_mark_char, CFString, kAXMenuItemMarkCharAttribute),
139    (menu_item_cmd_glyph, CFString, kAXMenuItemCmdGlyphAttribute),
140    (min_value, CFType, kAXMinValueAttribute),
141    (minimized, CFBoolean, kAXMinimizedAttribute),
142    (
143        number_of_characters,
144        CFNumber,
145        kAXNumberOfCharactersAttribute
146    ),
147    (parent, AXUIElement, kAXParentAttribute),
148    (placeholder_value, CFString, kAXPlaceholderValueAttribute),
149    (position, AXValue, kAXPositionAttribute),
150    (role, CFString, kAXRoleAttribute),
151    (role_description, CFString, kAXRoleDescriptionAttribute),
152    (
153        selected_children,
154        CFArray<AXUIElement>,
155        kAXSelectedChildrenAttribute
156    ),
157    (subrole, CFString, kAXSubroleAttribute),
158    (size, AXValue, kAXSizeAttribute),
159    (selected_text, CFString, kAXSelectedTextAttribute),
160    (selected_text_range, AXValue, kAXSelectedTextRangeAttribute),
161    (title, CFString, kAXTitleAttribute),
162    (
163        top_level_ui_element,
164        AXUIElement,
165        kAXTopLevelUIElementAttribute
166    ),
167    (value, CFType, kAXValueAttribute, set_value),
168    (value_description, CFString, kAXValueDescriptionAttribute),
169    (value_increment, CFType, kAXValueIncrementAttribute),
170    (
171        visible_children,
172        CFArray<AXUIElement>,
173        kAXVisibleChildrenAttribute
174    ),
175    (window, AXUIElement, kAXWindowAttribute),
176    (windows, CFArray<AXUIElement>, kAXWindowsAttribute),
177    (
178        visible_character_range,
179        AXValue,
180        kAXVisibleCharacterRangeAttribute
181    ),
182    // parameterized attributes
183    (
184        bounds_for_range,
185        AXValue,
186        kAXBoundsForRangeParameterizedAttribute
187    ),
188    (
189        line_for_index,
190        CFNumber,
191        kAXLineForIndexParameterizedAttribute
192    ),
193    (
194        range_for_line,
195        AXValue,
196        kAXRangeForLineParameterizedAttribute
197    ),
198    (
199        range_for_position,
200        AXValue,
201        kAXRangeForPositionParameterizedAttribute
202    ),
203    (
204        next_line_range_for_index,
205        AXValue,
206        kAXAXNextLineRangeForIndexParameterizedAttribute
207    ),
208    (
209        previous_line_range_for_index,
210        AXValue,
211        kAXAXPreviousLineRangeForIndexParameterizedAttribute
212    ),
213    (
214        attributed_string_for_range,
215        CFAttributedString,
216        kAXAttributedStringForRangeParameterizedAttribute
217    ),
218];