screen_capture_kit/
shareable_content.rs

1use block2::RcBlock;
2use core_graphics::{display::CGDirectDisplayID, window::CGWindowID};
3use libc::pid_t;
4use objc2::{extern_class, msg_send, msg_send_id, mutability::InteriorMutable, rc::Id, ClassType};
5use objc2_foundation::{CGRect, NSArray, NSError, NSInteger, NSObject, NSObjectProtocol, NSString};
6
7extern_class!(
8    #[derive(Debug, PartialEq, Eq, Hash)]
9    pub struct SCRunningApplication;
10
11    unsafe impl ClassType for SCRunningApplication {
12        type Super = NSObject;
13        type Mutability = InteriorMutable;
14    }
15);
16
17unsafe impl NSObjectProtocol for SCRunningApplication {}
18
19impl SCRunningApplication {
20    pub fn new() -> Id<Self> {
21        unsafe { msg_send_id![SCRunningApplication::class(), new] }
22    }
23
24    pub fn bundle_identifier(&self) -> Id<NSString> {
25        unsafe { msg_send_id![self, bundleIdentifier] }
26    }
27
28    pub fn application_name(&self) -> Id<NSString> {
29        unsafe { msg_send_id![self, applicationName] }
30    }
31
32    pub fn process_id(&self) -> pid_t {
33        unsafe { msg_send![self, processID] }
34    }
35}
36
37extern_class!(
38    #[derive(Debug, PartialEq, Eq, Hash)]
39    pub struct SCWindow;
40
41    unsafe impl ClassType for SCWindow {
42        type Super = NSObject;
43        type Mutability = InteriorMutable;
44    }
45);
46
47unsafe impl NSObjectProtocol for SCWindow {}
48
49impl SCWindow {
50    pub fn new() -> Id<Self> {
51        unsafe { msg_send_id![SCWindow::class(), new] }
52    }
53
54    pub fn window_id(&self) -> CGWindowID {
55        unsafe { msg_send![self, windowID] }
56    }
57
58    pub fn frame(&self) -> CGRect {
59        unsafe { msg_send![self, frame] }
60    }
61
62    pub fn title(&self) -> Option<Id<NSString>> {
63        unsafe { msg_send_id![self, title] }
64    }
65
66    pub fn window_layer(&self) -> NSInteger {
67        unsafe { msg_send![self, windowLayer] }
68    }
69
70    pub fn owning_application(&self) -> Option<Id<SCRunningApplication>> {
71        unsafe { msg_send_id![self, owningApplication] }
72    }
73
74    pub fn on_screen(&self) -> bool {
75        unsafe { msg_send![self, isOnScreen] }
76    }
77
78    pub fn active(&self) -> bool {
79        unsafe { msg_send![self, isActive] }
80    }
81}
82
83extern_class!(
84    #[derive(Debug, PartialEq, Eq, Hash)]
85    pub struct SCDisplay;
86
87    unsafe impl ClassType for SCDisplay {
88        type Super = NSObject;
89        type Mutability = InteriorMutable;
90    }
91);
92
93unsafe impl NSObjectProtocol for SCDisplay {}
94
95impl SCDisplay {
96    pub fn new() -> Id<Self> {
97        unsafe { msg_send_id![SCDisplay::class(), new] }
98    }
99
100    pub fn display_id(&self) -> CGDirectDisplayID {
101        unsafe { msg_send![self, displayID] }
102    }
103
104    pub fn width(&self) -> NSInteger {
105        unsafe { msg_send![self, width] }
106    }
107
108    pub fn height(&self) -> NSInteger {
109        unsafe { msg_send![self, height] }
110    }
111
112    pub fn frame(&self) -> CGRect {
113        unsafe { msg_send![self, frame] }
114    }
115}
116
117extern_class!(
118    #[derive(Debug, PartialEq, Eq, Hash)]
119    pub struct SCShareableContent;
120
121    unsafe impl ClassType for SCShareableContent {
122        type Super = NSObject;
123        type Mutability = InteriorMutable;
124    }
125);
126
127unsafe impl NSObjectProtocol for SCShareableContent {}
128
129type CompletionHandler = RcBlock<dyn Fn(*mut SCShareableContent, *mut NSError)>;
130
131impl SCShareableContent {
132    pub fn new() -> Id<Self> {
133        unsafe { msg_send_id![SCShareableContent::class(), new] }
134    }
135
136    fn new_completion_handler<F>(closure: F) -> CompletionHandler
137    where
138        F: Fn(Option<Id<SCShareableContent>>, Option<Id<NSError>>) + 'static,
139    {
140        RcBlock::new(move |sc: *mut Self, error: *mut NSError| {
141            closure(
142                if sc.is_null() {
143                    None
144                } else {
145                    unsafe { Id::retain(sc) }
146                },
147                if error.is_null() {
148                    None
149                } else {
150                    unsafe { Id::retain(error) }
151                },
152            );
153        })
154    }
155
156    pub fn get_shareable_content_with_completion_closure<F>(closure: F)
157    where
158        F: Fn(Option<Id<SCShareableContent>>, Option<Id<NSError>>) + 'static,
159    {
160        let handler = Self::new_completion_handler(closure);
161        unsafe { msg_send![class!(SCShareableContent), getShareableContentWithCompletionHandler: &*handler] }
162    }
163
164    pub fn get_shareable_content_excluding_desktop_windows<F>(exclude_desktop_windows: bool, on_screen_windows_only: bool, closure: F)
165    where
166        F: Fn(Option<Id<SCShareableContent>>, Option<Id<NSError>>) + 'static,
167    {
168        let handler = Self::new_completion_handler(closure);
169        unsafe {
170            msg_send![class!(SCShareableContent), getShareableContentExcludingDesktopWindows: exclude_desktop_windows onScreenWindowsOnly: on_screen_windows_only completionHandler: &*handler]
171        }
172    }
173
174    pub fn get_shareable_content_excluding_desktop_windows_below_window<F>(exclude_desktop_windows: bool, window: &SCWindow, closure: F)
175    where
176        F: Fn(Option<Id<SCShareableContent>>, Option<Id<NSError>>) + 'static,
177    {
178        let handler = Self::new_completion_handler(closure);
179        unsafe {
180            msg_send![class!(SCShareableContent), getShareableContentExcludingDesktopWindows: exclude_desktop_windows onScreenWindowsOnlyBelowWindow: window completionHandler: &*handler]
181        }
182    }
183
184    pub fn get_shareable_content_excluding_desktop_windows_above_window<F>(&self, exclude_desktop_windows: bool, window: &SCWindow, closure: F)
185    where
186        F: Fn(Option<Id<SCShareableContent>>, Option<Id<NSError>>) + 'static,
187    {
188        let handler = Self::new_completion_handler(closure);
189        unsafe {
190            msg_send![class!(SCShareableContent), getShareableContentExcludingDesktopWindows: exclude_desktop_windows onScreenWindowsOnlyAboveWindow: window completionHandler: &*handler]
191        }
192    }
193
194    pub fn windows(&self) -> Id<NSArray<SCWindow>> {
195        unsafe { msg_send_id![self, windows] }
196    }
197
198    pub fn displays(&self) -> Id<NSArray<SCDisplay>> {
199        unsafe { msg_send_id![self, displays] }
200    }
201
202    pub fn applications(&self) -> Id<NSArray<SCRunningApplication>> {
203        unsafe { msg_send_id![self, applications] }
204    }
205}