screen_capture_kit/
shareable_content.rs1use 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}