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}