Skip to main content

screen_capture_kit/
shareable_content.rs

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