Skip to main content

windows_capture/
settings.rs

1use std::time::Duration;
2
3use windows::Graphics::Capture::GraphicsCaptureItem;
4
5use crate::graphics_capture_picker::HwndGuard;
6use crate::monitor::Monitor;
7use crate::window::Window;
8
9/// An enumeration of item types that can be captured.
10///
11/// Wraps the WinRT [`GraphicsCaptureItem`] together with additional details about the source:
12/// - [`Monitor`] for display monitors,
13/// - [`Window`] for top-level windows,
14/// - [`crate::graphics_capture_picker::HwndGuard`] for unknown HWND-based sources.
15pub enum GraphicsCaptureItemType {
16    /// A display monitor. Contains the [`GraphicsCaptureItem`] and its [`Monitor`] details.
17    Monitor((GraphicsCaptureItem, Monitor)),
18    /// An application window. Contains the [`GraphicsCaptureItem`] and its [`Window`] details.
19    Window((GraphicsCaptureItem, Window)),
20    /// An unknown capture item type (typically created from an HWND). Contains the
21    /// [`GraphicsCaptureItem`] and the associated
22    /// [`crate::graphics_capture_picker::HwndGuard`].
23    Unknown((GraphicsCaptureItem, HwndGuard)),
24}
25
26/// Specifies the pixel format for the captured frame.
27#[derive(Eq, PartialEq, Clone, Copy, Debug)]
28pub enum ColorFormat {
29    /// 16-bit floating-point RGBA format.
30    Rgba16F = 10,
31    /// 8-bit unsigned integer RGBA format.
32    Rgba8 = 28,
33    /// 8-bit unsigned integer BGRA format.
34    Bgra8 = 87,
35}
36
37impl Default for ColorFormat {
38    /// The default color format is [`ColorFormat::Rgba8`].
39    #[inline]
40    fn default() -> Self {
41        Self::Rgba8
42    }
43}
44
45/// Defines whether the cursor should be visible in the captured output.
46#[derive(Eq, PartialEq, Clone, Copy, Debug)]
47pub enum CursorCaptureSettings {
48    /// Use the system's default behavior for cursor visibility.
49    Default,
50    /// Ensure the cursor is always visible in the capture.
51    WithCursor,
52    /// Ensure the cursor is never visible in the capture.
53    WithoutCursor,
54}
55
56/// Defines whether a border should be drawn around the captured item.
57#[derive(Eq, PartialEq, Clone, Copy, Debug)]
58pub enum DrawBorderSettings {
59    /// Use the system's default behavior for the capture border.
60    Default,
61    /// Draw a border around the captured item.
62    WithBorder,
63    /// Do not draw a border around the captured item.
64    WithoutBorder,
65}
66
67/// Defines whether to include or exclude secondary windows in the capture.
68#[derive(Eq, PartialEq, Clone, Copy, Debug)]
69pub enum SecondaryWindowSettings {
70    /// Use the system's default behavior for capturing secondary windows.
71    Default,
72    /// Include secondary windows in the capture.
73    Include,
74    /// Exclude secondary windows from the capture.
75    Exclude,
76}
77
78/// Controls the minimum interval between frame updates requested from Windows Graphics Capture.
79///
80/// This is an OS-side throttle, not a target frame rate. A custom interval limits how frequently
81/// updates are eligible for delivery, but it does not make Windows produce frames periodically or
82/// guarantee a constant rate. The actual rate can be lower and depends on source/compositor
83/// updates, display timing, system load, and how quickly captured frames are consumed.
84///
85/// Consumers that require a fixed cadence must pace the output themselves, dropping excess frames
86/// or duplicating the latest frame when necessary. [`crate::frame::Frame::timestamp`] provides the
87/// capture timestamp for that purpose.
88#[derive(Eq, PartialEq, Clone, Copy, Debug)]
89pub enum MinimumUpdateIntervalSettings {
90    /// Leave the Windows Graphics Capture update interval unchanged.
91    Default,
92    /// Request a custom minimum interval between eligible frame updates.
93    Custom(Duration),
94}
95
96/// Defines how the system should handle dirty regions, which are areas of the screen that have
97/// changed.
98#[derive(Eq, PartialEq, Clone, Copy, Debug)]
99pub enum DirtyRegionSettings {
100    /// Use the system's default behavior for dirty regions.
101    Default,
102    /// Only report the dirty regions without rendering them separately.
103    ReportOnly,
104    /// Report and render the dirty regions.
105    ReportAndRender,
106}
107
108/// Represents the settings for a screen capture session.
109#[derive(Eq, PartialEq, Clone, Debug)]
110pub struct Settings<Flags, T: TryInto<GraphicsCaptureItemType>> {
111    /// The item to be captured (e.g., a `Window` or `Monitor`).
112    pub(crate) item: T,
113    /// Specifies whether the cursor should be captured.
114    pub(crate) cursor_capture_settings: CursorCaptureSettings,
115    /// Specifies whether a border should be drawn around the captured item.
116    pub(crate) draw_border_settings: DrawBorderSettings,
117    /// Specifies whether to include secondary windows in the capture.
118    pub(crate) secondary_window_settings: SecondaryWindowSettings,
119    /// Specifies the minimum time between frame updates.
120    pub(crate) minimum_update_interval_settings: MinimumUpdateIntervalSettings,
121    /// Specifies how to handle dirty regions.
122    pub(crate) dirty_region_settings: DirtyRegionSettings,
123    /// The pixel format for the captured frames.
124    pub(crate) color_format: ColorFormat,
125    /// User-defined flags that can be passed to the capture implementation.
126    pub(crate) flags: Flags,
127}
128
129impl<Flags, T: TryInto<GraphicsCaptureItemType>> Settings<Flags, T> {
130    /// Constructs a new [`Settings`] configuration.
131    #[inline]
132    #[must_use]
133    #[allow(clippy::too_many_arguments)]
134    pub const fn new(
135        item: T,
136        cursor_capture_settings: CursorCaptureSettings,
137        draw_border_settings: DrawBorderSettings,
138        secondary_window_settings: SecondaryWindowSettings,
139        minimum_update_interval_settings: MinimumUpdateIntervalSettings,
140        dirty_region_settings: DirtyRegionSettings,
141        color_format: ColorFormat,
142        flags: Flags,
143    ) -> Self {
144        Self {
145            item,
146            cursor_capture_settings,
147            draw_border_settings,
148            secondary_window_settings,
149            minimum_update_interval_settings,
150            dirty_region_settings,
151            color_format,
152            flags,
153        }
154    }
155
156    /// Returns a reference to the capture item.
157    #[inline]
158    #[must_use]
159    pub const fn item(&self) -> &T {
160        &self.item
161    }
162
163    /// Returns the cursor capture settings.
164    #[inline]
165    #[must_use]
166    pub const fn cursor_capture(&self) -> CursorCaptureSettings {
167        self.cursor_capture_settings
168    }
169
170    /// Returns the draw border settings.
171    #[inline]
172    #[must_use]
173    pub const fn draw_border(&self) -> DrawBorderSettings {
174        self.draw_border_settings
175    }
176
177    /// Returns the secondary window settings.
178    #[inline]
179    #[must_use]
180    pub const fn secondary_window(&self) -> SecondaryWindowSettings {
181        self.secondary_window_settings
182    }
183
184    /// Returns the minimum update interval settings.
185    #[inline]
186    #[must_use]
187    pub const fn minimum_update_interval(&self) -> MinimumUpdateIntervalSettings {
188        self.minimum_update_interval_settings
189    }
190
191    /// Returns the dirty region settings.
192    #[inline]
193    #[must_use]
194    pub const fn dirty_region(&self) -> DirtyRegionSettings {
195        self.dirty_region_settings
196    }
197
198    /// Returns the color format.
199    #[inline]
200    #[must_use]
201    pub const fn color_format(&self) -> ColorFormat {
202        self.color_format
203    }
204
205    /// Returns a reference to the flags.
206    #[inline]
207    #[must_use]
208    pub const fn flags(&self) -> &Flags {
209        &self.flags
210    }
211}