Skip to main content

screencapturekit/stream/configuration/
advanced.rs

1use super::internal::SCStreamConfiguration;
2#[cfg(feature = "macos_14_0")]
3use crate::error::{SCError, SCResult};
4
5/// Presenter overlay privacy alert setting (macOS 14.0+)
6///
7/// Controls when the system displays a privacy alert for presenter overlay.
8#[repr(i32)]
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
10pub enum SCPresenterOverlayAlertSetting {
11    /// Let the system decide when to show the alert
12    #[default]
13    System = 0,
14    /// Never show the privacy alert
15    Never = 1,
16    /// Always show the privacy alert
17    Always = 2,
18}
19
20impl SCPresenterOverlayAlertSetting {
21    pub const fn from_raw(raw: i32) -> Option<Self> {
22        match raw {
23            0 => Some(Self::System),
24            1 => Some(Self::Never),
25            2 => Some(Self::Always),
26            _ => None,
27        }
28    }
29}
30
31impl SCStreamConfiguration {
32    /// Sets whether to ignore shadows for single window capture.
33    ///
34    /// A Boolean value that indicates whether the stream omits the shadow effects
35    /// of the windows it captures.
36    /// Available on macOS 14.0+
37    ///
38    /// Requires the `macos_14_0` feature flag to be enabled.
39    #[cfg(feature = "macos_14_0")]
40    #[allow(clippy::missing_errors_doc)]
41    pub fn set_ignores_shadows_single_window(
42        &mut self,
43        ignores_shadows: bool,
44    ) -> SCResult<&mut Self> {
45        let applied = unsafe {
46            crate::ffi::sc_stream_configuration_set_ignores_shadows_single_window(
47                self.as_ptr(),
48                ignores_shadows,
49            )
50        };
51        applied.then_some(self).ok_or_else(|| {
52            SCError::feature_not_available(
53                "SCStreamConfiguration.ignoreShadowsSingleWindow",
54                "14.0",
55            )
56        })
57    }
58
59    /// Sets whether to ignore shadows for single window capture (builder pattern)
60    #[cfg(feature = "macos_14_0")]
61    #[allow(clippy::missing_errors_doc)]
62    pub fn with_ignores_shadows_single_window(mut self, ignores_shadows: bool) -> SCResult<Self> {
63        self.set_ignores_shadows_single_window(ignores_shadows)?;
64        Ok(self)
65    }
66
67    /// Get whether shadows are ignored for single-window capture (macOS 14.0+).
68    #[cfg(feature = "macos_14_0")]
69    pub fn ignores_shadows_single_window(&self) -> bool {
70        unsafe {
71            crate::ffi::sc_stream_configuration_get_ignores_shadows_single_window(self.as_ptr())
72        }
73    }
74
75    /// Sets whether captured content should be treated as opaque.
76    ///
77    /// A Boolean value that indicates whether the stream treats the transparency
78    /// of the captured content as opaque.
79    ///
80    /// Available on macOS 14.0+ (`SCStreamConfiguration.shouldBeOpaque` is
81    /// annotated `API_AVAILABLE(macos(14.0))`), so this requires the
82    /// `macos_14_0` feature flag. On older systems it returns
83    /// [`SCError::FeatureNotAvailable`].
84    #[cfg(feature = "macos_14_0")]
85    #[allow(clippy::missing_errors_doc)]
86    pub fn set_should_be_opaque(&mut self, should_be_opaque: bool) -> SCResult<&mut Self> {
87        let applied = unsafe {
88            crate::ffi::sc_stream_configuration_set_should_be_opaque(
89                self.as_ptr(),
90                should_be_opaque,
91            )
92        };
93        applied.then_some(self).ok_or_else(|| {
94            SCError::feature_not_available("SCStreamConfiguration.shouldBeOpaque", "14.0")
95        })
96    }
97
98    /// Sets whether captured content should be treated as opaque (builder pattern)
99    #[cfg(feature = "macos_14_0")]
100    #[allow(clippy::missing_errors_doc)]
101    pub fn with_should_be_opaque(mut self, should_be_opaque: bool) -> SCResult<Self> {
102        self.set_should_be_opaque(should_be_opaque)?;
103        Ok(self)
104    }
105
106    /// Get whether captured content is treated as opaque (macOS 14.0+).
107    #[cfg(feature = "macos_14_0")]
108    pub fn should_be_opaque(&self) -> bool {
109        unsafe { crate::ffi::sc_stream_configuration_get_should_be_opaque(self.as_ptr()) }
110    }
111
112    /// Sets whether to include child windows in capture.
113    ///
114    /// A Boolean value that indicates whether the content includes child windows.
115    /// Available on macOS 14.2+
116    ///
117    /// Requires the `macos_14_2` feature flag to be enabled.
118    #[cfg(feature = "macos_14_2")]
119    #[allow(clippy::missing_errors_doc)]
120    pub fn set_includes_child_windows(
121        &mut self,
122        includes_child_windows: bool,
123    ) -> SCResult<&mut Self> {
124        let applied = unsafe {
125            crate::ffi::sc_stream_configuration_set_includes_child_windows(
126                self.as_ptr(),
127                includes_child_windows,
128            )
129        };
130        applied.then_some(self).ok_or_else(|| {
131            SCError::feature_not_available("SCStreamConfiguration.includeChildWindows", "14.2")
132        })
133    }
134
135    /// Sets whether to include child windows (builder pattern)
136    #[cfg(feature = "macos_14_2")]
137    #[allow(clippy::missing_errors_doc)]
138    pub fn with_includes_child_windows(mut self, includes_child_windows: bool) -> SCResult<Self> {
139        self.set_includes_child_windows(includes_child_windows)?;
140        Ok(self)
141    }
142
143    /// Get whether child windows are included (macOS 14.2+).
144    #[cfg(feature = "macos_14_2")]
145    pub fn includes_child_windows(&self) -> bool {
146        unsafe { crate::ffi::sc_stream_configuration_get_includes_child_windows(self.as_ptr()) }
147    }
148
149    /// Sets the presenter overlay privacy alert setting.
150    ///
151    /// A configuration for the privacy alert that the capture session displays.
152    ///
153    /// Available on macOS 14.0+ — `presenterOverlayPrivacyAlertSetting` is
154    /// annotated `API_AVAILABLE(macos(14.0))`, not 14.2 as this binding
155    /// previously assumed — so it only needs the `macos_14_0` feature flag.
156    #[cfg(feature = "macos_14_0")]
157    #[allow(clippy::missing_errors_doc)]
158    pub fn set_presenter_overlay_privacy_alert_setting(
159        &mut self,
160        setting: SCPresenterOverlayAlertSetting,
161    ) -> SCResult<&mut Self> {
162        let applied = unsafe {
163            crate::ffi::sc_stream_configuration_set_presenter_overlay_privacy_alert_setting(
164                self.as_ptr(),
165                setting as i32,
166            )
167        };
168        if applied {
169            Ok(self)
170        } else {
171            Err(SCError::feature_not_available(
172                "SCStreamConfiguration.presenterOverlayPrivacyAlertSetting",
173                "14.0",
174            ))
175        }
176    }
177
178    /// Sets the presenter overlay privacy alert setting (builder pattern, macOS 14.0+)
179    #[cfg(feature = "macos_14_0")]
180    #[allow(clippy::missing_errors_doc)]
181    pub fn with_presenter_overlay_privacy_alert_setting(
182        mut self,
183        setting: SCPresenterOverlayAlertSetting,
184    ) -> SCResult<Self> {
185        self.set_presenter_overlay_privacy_alert_setting(setting)?;
186        Ok(self)
187    }
188
189    /// Get the presenter overlay privacy alert setting (macOS 14.0+).
190    #[cfg(feature = "macos_14_0")]
191    #[allow(clippy::missing_errors_doc)]
192    pub fn presenter_overlay_privacy_alert_setting(
193        &self,
194    ) -> SCResult<SCPresenterOverlayAlertSetting> {
195        let mut raw = 0_i32;
196        let available = unsafe {
197            crate::ffi::sc_stream_configuration_get_presenter_overlay_privacy_alert_setting(
198                self.as_ptr(),
199                &raw mut raw,
200            )
201        };
202        if !available {
203            return Err(SCError::feature_not_available(
204                "SCStreamConfiguration.presenterOverlayPrivacyAlertSetting",
205                "14.0",
206            ));
207        }
208        SCPresenterOverlayAlertSetting::from_raw(raw).ok_or_else(|| SCError::UnknownValue {
209            type_name: "SCPresenterOverlayAlertSetting",
210            raw: i64::from(raw),
211        })
212    }
213
214    /// Sets whether to ignore shadow display configuration.
215    ///
216    /// Available on macOS 14.0+
217    ///
218    /// Requires the `macos_14_0` feature flag to be enabled.
219    #[cfg(feature = "macos_14_0")]
220    #[allow(clippy::missing_errors_doc)]
221    pub fn set_ignores_shadow_display_configuration(
222        &mut self,
223        ignores_shadow: bool,
224    ) -> SCResult<&mut Self> {
225        let applied = unsafe {
226            crate::ffi::sc_stream_configuration_set_ignores_shadow_display_configuration(
227                self.as_ptr(),
228                ignores_shadow,
229            )
230        };
231        applied.then_some(self).ok_or_else(|| {
232            SCError::feature_not_available("SCStreamConfiguration.ignoreShadowsDisplay", "14.0")
233        })
234    }
235
236    /// Sets whether to ignore shadow display configuration (builder pattern)
237    #[cfg(feature = "macos_14_0")]
238    #[allow(clippy::missing_errors_doc)]
239    pub fn with_ignores_shadow_display_configuration(
240        mut self,
241        ignores_shadow: bool,
242    ) -> SCResult<Self> {
243        self.set_ignores_shadow_display_configuration(ignores_shadow)?;
244        Ok(self)
245    }
246
247    /// Get whether the shadow display configuration is ignored (macOS 14.0+).
248    #[cfg(feature = "macos_14_0")]
249    pub fn ignores_shadow_display_configuration(&self) -> bool {
250        unsafe {
251            crate::ffi::sc_stream_configuration_get_ignores_shadow_display_configuration(
252                self.as_ptr(),
253            )
254        }
255    }
256}
257
258#[cfg(all(test, feature = "macos_14_0"))]
259mod tests {
260    use super::{SCPresenterOverlayAlertSetting, SCStreamConfiguration};
261
262    #[test]
263    fn bridge_rejects_unknown_presenter_overlay_raw_values() {
264        let mut config = SCStreamConfiguration::new();
265        config
266            .set_presenter_overlay_privacy_alert_setting(SCPresenterOverlayAlertSetting::Never)
267            .expect("set the presenter overlay privacy alert setting");
268        for raw in [3, -1, i32::MAX, i32::MIN] {
269            let applied = unsafe {
270                crate::ffi::sc_stream_configuration_set_presenter_overlay_privacy_alert_setting(
271                    config.as_ptr(),
272                    raw,
273                )
274            };
275            assert!(!applied, "the bridge accepted raw value {raw}");
276            assert_eq!(
277                config.presenter_overlay_privacy_alert_setting(),
278                Ok(SCPresenterOverlayAlertSetting::Never)
279            );
280        }
281    }
282}