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