window_observer/platform_impl/macos/
window.rs1use accessibility::{AXUIElement, AXUIElementAttributes};
2use core_foundation::base::TCFType;
3use objc2_core_foundation::{CGPoint, CGSize};
4
5use super::{
6 binding_ax_function::{ax_ui_element_copy_attribute_value, ax_value_get_value},
7 error::MacOSError,
8};
9use crate::window::{Position, Size};
10
11impl From<CGSize> for Size {
12 fn from(size: CGSize) -> Self {
13 Size {
14 width: size.width as _,
15 height: size.height as _,
16 }
17 }
18}
19
20impl From<CGPoint> for Position {
21 fn from(point: CGPoint) -> Self {
22 Position {
23 x: point.x as _,
24 y: point.y as _,
25 }
26 }
27}
28
29#[derive(Debug, Clone, PartialEq, Eq)]
32pub struct WindowUIElement(AXUIElement);
33
34unsafe impl Send for WindowUIElement {}
35unsafe impl Sync for WindowUIElement {}
36
37impl WindowUIElement {
38 pub fn new(element: AXUIElement) -> Self {
46 Self(element)
47 }
48
49 pub fn ax_ui_element(&self) -> &AXUIElement {
51 &self.0
52 }
53
54 fn get<T>(
56 &self,
57 attribute: &str,
58 r#type: accessibility_sys::AXValueType,
59 ) -> Result<T, MacOSError> {
60 let ax_value =
61 ax_ui_element_copy_attribute_value(&self.0, attribute).map_err(MacOSError::Ax)?;
62 Ok(unsafe {
63 ax_value_get_value::<T>(ax_value.as_CFTypeRef() as _, r#type)
64 .expect("AXValue is not this type")
65 })
66 }
67
68 pub fn title(&self) -> Result<String, MacOSError> {
70 Ok(self.0.title()?.to_string())
71 }
72
73 pub fn size(&self) -> Result<Size, MacOSError> {
75 self.get::<CGSize>(
76 accessibility_sys::kAXSizeAttribute,
77 accessibility_sys::kAXValueTypeCGSize,
78 )
79 .map(|v| v.into())
80 }
81
82 pub fn position(&self) -> Result<Position, MacOSError> {
84 self.get::<CGPoint>(
85 accessibility_sys::kAXPositionAttribute,
86 accessibility_sys::kAXValueTypeCGPoint,
87 )
88 .map(|v| v.into())
89 }
90
91 pub fn is_focused(&self) -> Result<bool, MacOSError> {
93 Ok(self.0.focused()?.into())
94 }
95
96 #[cfg(feature = "macos-private-api")]
105 #[cfg_attr(docsrs, doc(cfg(feature = "macos-private-api")))]
106 pub fn id(&self) -> Result<u32, MacOSError> {
107 super::binding_ax_function::ax_ui_element_get_window_id(&self.0)
108 }
109}