Skip to main content

cart_tmp_winit/
window.rs

1//! The `Window` struct and associated types.
2use std::fmt;
3
4use crate::{
5    dpi::{PhysicalPosition, PhysicalSize, Position, Size},
6    error::{ExternalError, NotSupportedError, OsError},
7    event_loop::EventLoopWindowTarget,
8    monitor::{MonitorHandle, VideoMode},
9    platform_impl,
10};
11
12pub use crate::icon::{BadIcon, Icon};
13
14/// Represents a window.
15///
16/// # Example
17///
18/// ```no_run
19/// use winit::{
20///     event::{Event, WindowEvent},
21///     event_loop::{ControlFlow, EventLoop},
22///     window::Window,
23/// };
24///
25/// let mut event_loop = EventLoop::new();
26/// let window = Window::new(&event_loop).unwrap();
27///
28/// event_loop.run(move |event, _, control_flow| {
29///     *control_flow = ControlFlow::Wait;
30///
31///     match event {
32///         Event::WindowEvent {
33///             event: WindowEvent::CloseRequested,
34///             ..
35///         } => *control_flow = ControlFlow::Exit,
36///         _ => (),
37///     }
38/// });
39/// ```
40pub struct Window {
41    pub(crate) window: platform_impl::Window,
42}
43
44impl fmt::Debug for Window {
45    fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result {
46        fmtr.pad("Window { .. }")
47    }
48}
49
50impl Drop for Window {
51    fn drop(&mut self) {
52        // If the window is in exclusive fullscreen, we must restore the desktop
53        // video mode (generally this would be done on application exit, but
54        // closing the window doesn't necessarily always mean application exit,
55        // such as when there are multiple windows)
56        if let Some(Fullscreen::Exclusive(_)) = self.fullscreen() {
57            self.set_fullscreen(None);
58        }
59    }
60}
61
62/// Identifier of a window. Unique for each window.
63///
64/// Can be obtained with `window.id()`.
65///
66/// Whenever you receive an event specific to a window, this event contains a `WindowId` which you
67/// can then compare to the ids of your windows.
68#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
69pub struct WindowId(pub(crate) platform_impl::WindowId);
70
71impl WindowId {
72    /// Returns a dummy `WindowId`, useful for unit testing. The only guarantee made about the return
73    /// value of this function is that it will always be equal to itself and to future values returned
74    /// by this function.  No other guarantees are made. This may be equal to a real `WindowId`.
75    ///
76    /// **Passing this into a winit function will result in undefined behavior.**
77    pub unsafe fn dummy() -> Self {
78        WindowId(platform_impl::WindowId::dummy())
79    }
80}
81
82/// Object that allows you to build windows.
83#[derive(Clone, Default)]
84pub struct WindowBuilder {
85    /// The attributes to use to create the window.
86    pub window: WindowAttributes,
87
88    // Platform-specific configuration.
89    pub(crate) platform_specific: platform_impl::PlatformSpecificWindowBuilderAttributes,
90}
91
92impl fmt::Debug for WindowBuilder {
93    fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result {
94        fmtr.debug_struct("WindowBuilder")
95            .field("window", &self.window)
96            .finish()
97    }
98}
99
100/// Attributes to use when creating a window.
101#[derive(Debug, Clone)]
102pub struct WindowAttributes {
103    /// The dimensions of the window. If this is `None`, some platform-specific dimensions will be
104    /// used.
105    ///
106    /// The default is `None`.
107    pub inner_size: Option<Size>,
108
109    /// The minimum dimensions a window can be, If this is `None`, the window will have no minimum dimensions (aside from reserved).
110    ///
111    /// The default is `None`.
112    pub min_inner_size: Option<Size>,
113
114    /// The maximum dimensions a window can be, If this is `None`, the maximum will have no maximum or will be set to the primary monitor's dimensions by the platform.
115    ///
116    /// The default is `None`.
117    pub max_inner_size: Option<Size>,
118
119    /// Whether the window is resizable or not.
120    ///
121    /// The default is `true`.
122    pub resizable: bool,
123
124    /// Whether the window should be set as fullscreen upon creation.
125    ///
126    /// The default is `None`.
127    pub fullscreen: Option<Fullscreen>,
128
129    /// The title of the window in the title bar.
130    ///
131    /// The default is `"winit window"`.
132    pub title: String,
133
134    /// Whether the window should be maximized upon creation.
135    ///
136    /// The default is `false`.
137    pub maximized: bool,
138
139    /// Whether the window should be immediately visible upon creation.
140    ///
141    /// The default is `true`.
142    pub visible: bool,
143
144    /// Whether the the window should be transparent. If this is true, writing colors
145    /// with alpha values different than `1.0` will produce a transparent window.
146    ///
147    /// The default is `false`.
148    pub transparent: bool,
149
150    /// Whether the window should have borders and bars.
151    ///
152    /// The default is `true`.
153    pub decorations: bool,
154
155    /// Whether the window should always be on top of other windows.
156    ///
157    /// The default is `false`.
158    pub always_on_top: bool,
159
160    /// The window icon.
161    ///
162    /// The default is `None`.
163    pub window_icon: Option<Icon>,
164}
165
166impl Default for WindowAttributes {
167    #[inline]
168    fn default() -> WindowAttributes {
169        WindowAttributes {
170            inner_size: None,
171            min_inner_size: None,
172            max_inner_size: None,
173            resizable: true,
174            title: "winit window".to_owned(),
175            maximized: false,
176            fullscreen: None,
177            visible: true,
178            transparent: false,
179            decorations: true,
180            always_on_top: false,
181            window_icon: None,
182        }
183    }
184}
185
186impl WindowBuilder {
187    /// Initializes a new `WindowBuilder` with default values.
188    #[inline]
189    pub fn new() -> Self {
190        Default::default()
191    }
192
193    /// Requests the window to be of specific dimensions.
194    ///
195    /// See [`Window::set_inner_size`] for details.
196    ///
197    /// [`Window::set_inner_size`]: crate::window::Window::set_inner_size
198    #[inline]
199    pub fn with_inner_size<S: Into<Size>>(mut self, size: S) -> Self {
200        self.window.inner_size = Some(size.into());
201        self
202    }
203
204    /// Sets a minimum dimension size for the window.
205    ///
206    /// See [`Window::set_min_inner_size`] for details.
207    ///
208    /// [`Window::set_min_inner_size`]: crate::window::Window::set_min_inner_size
209    #[inline]
210    pub fn with_min_inner_size<S: Into<Size>>(mut self, min_size: S) -> Self {
211        self.window.min_inner_size = Some(min_size.into());
212        self
213    }
214
215    /// Sets a maximum dimension size for the window.
216    ///
217    /// See [`Window::set_max_inner_size`] for details.
218    ///
219    /// [`Window::set_max_inner_size`]: crate::window::Window::set_max_inner_size
220    #[inline]
221    pub fn with_max_inner_size<S: Into<Size>>(mut self, max_size: S) -> Self {
222        self.window.max_inner_size = Some(max_size.into());
223        self
224    }
225
226    /// Sets whether the window is resizable or not.
227    ///
228    /// See [`Window::set_resizable`] for details.
229    ///
230    /// [`Window::set_resizable`]: crate::window::Window::set_resizable
231    #[inline]
232    pub fn with_resizable(mut self, resizable: bool) -> Self {
233        self.window.resizable = resizable;
234        self
235    }
236
237    /// Requests a specific title for the window.
238    ///
239    /// See [`Window::set_title`] for details.
240    ///
241    /// [`Window::set_title`]: crate::window::Window::set_title
242    #[inline]
243    pub fn with_title<T: Into<String>>(mut self, title: T) -> Self {
244        self.window.title = title.into();
245        self
246    }
247
248    /// Sets the window fullscreen state.
249    ///
250    /// See [`Window::set_fullscreen`] for details.
251    ///
252    /// [`Window::set_fullscreen`]: crate::window::Window::set_fullscreen
253    #[inline]
254    pub fn with_fullscreen(mut self, fullscreen: Option<Fullscreen>) -> Self {
255        self.window.fullscreen = fullscreen;
256        self
257    }
258
259    /// Requests maximized mode.
260    ///
261    /// See [`Window::set_maximized`] for details.
262    ///
263    /// [`Window::set_maximized`]: crate::window::Window::set_maximized
264    #[inline]
265    pub fn with_maximized(mut self, maximized: bool) -> Self {
266        self.window.maximized = maximized;
267        self
268    }
269
270    /// Sets whether the window will be initially hidden or visible.
271    ///
272    /// See [`Window::set_visible`] for details.
273    ///
274    /// [`Window::set_visible`]: crate::window::Window::set_visible
275    #[inline]
276    pub fn with_visible(mut self, visible: bool) -> Self {
277        self.window.visible = visible;
278        self
279    }
280
281    /// Sets whether the background of the window should be transparent.
282    #[inline]
283    pub fn with_transparent(mut self, transparent: bool) -> Self {
284        self.window.transparent = transparent;
285        self
286    }
287
288    /// Sets whether the window should have a border, a title bar, etc.
289    ///
290    /// See [`Window::set_decorations`] for details.
291    ///
292    /// [`Window::set_decorations`]: crate::window::Window::set_decorations
293    #[inline]
294    pub fn with_decorations(mut self, decorations: bool) -> Self {
295        self.window.decorations = decorations;
296        self
297    }
298
299    /// Sets whether or not the window will always be on top of other windows.
300    ///
301    /// See [`Window::set_always_on_top`] for details.
302    ///
303    /// [`Window::set_always_on_top`]: crate::window::Window::set_always_on_top
304    #[inline]
305    pub fn with_always_on_top(mut self, always_on_top: bool) -> Self {
306        self.window.always_on_top = always_on_top;
307        self
308    }
309
310    /// Sets the window icon.
311    ///
312    /// See [`Window::set_window_icon`] for details.
313    ///
314    /// [`Window::set_window_icon`]: crate::window::Window::set_window_icon
315    #[inline]
316    pub fn with_window_icon(mut self, window_icon: Option<Icon>) -> Self {
317        self.window.window_icon = window_icon;
318        self
319    }
320
321    /// Builds the window.
322    ///
323    /// Possible causes of error include denied permission, incompatible system, and lack of memory.
324    ///
325    /// Platform-specific behavior:
326    /// - **Web**: The window is created but not inserted into the web page automatically. Please
327    /// see the web platform module for more information.
328    #[inline]
329    pub fn build<T: 'static>(
330        self,
331        window_target: &EventLoopWindowTarget<T>,
332    ) -> Result<Window, OsError> {
333        platform_impl::Window::new(&window_target.p, self.window, self.platform_specific).map(
334            |window| {
335                window.request_redraw();
336                Window { window }
337            },
338        )
339    }
340}
341
342/// Base Window functions.
343impl Window {
344    /// Creates a new Window for platforms where this is appropriate.
345    ///
346    /// This function is equivalent to [`WindowBuilder::new().build(event_loop)`].
347    ///
348    /// Error should be very rare and only occur in case of permission denied, incompatible system,
349    ///  out of memory, etc.
350    ///
351    /// Platform-specific behavior:
352    /// - **Web**: The window is created but not inserted into the web page automatically. Please
353    /// see the web platform module for more information.
354    ///
355    /// [`WindowBuilder::new().build(event_loop)`]: crate::window::WindowBuilder::build
356    #[inline]
357    pub fn new<T: 'static>(event_loop: &EventLoopWindowTarget<T>) -> Result<Window, OsError> {
358        let builder = WindowBuilder::new();
359        builder.build(event_loop)
360    }
361
362    /// Returns an identifier unique to the window.
363    #[inline]
364    pub fn id(&self) -> WindowId {
365        WindowId(self.window.id())
366    }
367
368    /// Returns the scale factor that can be used to map logical pixels to physical pixels, and vice versa.
369    ///
370    /// See the [`dpi`](crate::dpi) module for more information.
371    ///
372    /// Note that this value can change depending on user action (for example if the window is
373    /// moved to another screen); as such, tracking `WindowEvent::ScaleFactorChanged` events is
374    /// the most robust way to track the DPI you need to use to draw.
375    ///
376    /// ## Platform-specific
377    ///
378    /// - **X11:** This respects Xft.dpi, and can be overridden using the `WINIT_X11_SCALE_FACTOR` environment variable.
379    /// - **Android:** Always returns 1.0.
380    /// - **iOS:** Can only be called on the main thread. Returns the underlying `UIView`'s
381    ///   [`contentScaleFactor`].
382    ///
383    /// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
384    #[inline]
385    pub fn scale_factor(&self) -> f64 {
386        self.window.scale_factor()
387    }
388
389    /// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS
390    /// events have been processed by the event loop.
391    ///
392    /// This is the **strongly encouraged** method of redrawing windows, as it can integrate with
393    /// OS-requested redraws (e.g. when a window gets resized).
394    ///
395    /// This function can cause `RedrawRequested` events to be emitted after `Event::MainEventsCleared`
396    /// but before `Event::NewEvents` if called in the following circumstances:
397    /// * While processing `MainEventsCleared`.
398    /// * While processing a `RedrawRequested` event that was sent during `MainEventsCleared` or any
399    ///   directly subsequent `RedrawRequested` event.
400    ///
401    /// ## Platform-specific
402    ///
403    /// - **iOS:** Can only be called on the main thread.
404    /// - **Android:** Unsupported.
405    #[inline]
406    pub fn request_redraw(&self) {
407        self.window.request_redraw()
408    }
409}
410
411/// Position and size functions.
412impl Window {
413    /// Returns the position of the top-left hand corner of the window's client area relative to the
414    /// top-left hand corner of the desktop.
415    ///
416    /// The same conditions that apply to `outer_position` apply to this method.
417    ///
418    /// ## Platform-specific
419    ///
420    /// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
421    ///   window's [safe area] in the screen space coordinate system.
422    /// - **Web:** Returns the top-left coordinates relative to the viewport. _Note: this returns the
423    ///    same value as `outer_position`._
424    /// - **Android / Wayland:** Always returns [`NotSupportedError`].
425    ///
426    /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
427    #[inline]
428    pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
429        self.window.inner_position()
430    }
431
432    /// Returns the position of the top-left hand corner of the window relative to the
433    ///  top-left hand corner of the desktop.
434    ///
435    /// Note that the top-left hand corner of the desktop is not necessarily the same as
436    ///  the screen. If the user uses a desktop with multiple monitors, the top-left hand corner
437    ///  of the desktop is the top-left hand corner of the monitor at the top-left of the desktop.
438    ///
439    /// The coordinates can be negative if the top-left hand corner of the window is outside
440    ///  of the visible screen region.
441    ///
442    /// ## Platform-specific
443    ///
444    /// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
445    ///   window in the screen space coordinate system.
446    /// - **Web:** Returns the top-left coordinates relative to the viewport.
447    /// - **Android / Wayland:** Always returns [`NotSupportedError`].
448    #[inline]
449    pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
450        self.window.outer_position()
451    }
452
453    /// Modifies the position of the window.
454    ///
455    /// See `outer_position` for more information about the coordinates. This automatically un-maximizes the
456    /// window if it's maximized.
457    ///
458    /// ## Platform-specific
459    ///
460    /// - **iOS:** Can only be called on the main thread. Sets the top left coordinates of the
461    ///   window in the screen space coordinate system.
462    /// - **Web:** Sets the top-left coordinates relative to the viewport.
463    /// - **Android / Wayland:** Unsupported.
464    #[inline]
465    pub fn set_outer_position<P: Into<Position>>(&self, position: P) {
466        self.window.set_outer_position(position.into())
467    }
468
469    /// Returns the physical size of the window's client area.
470    ///
471    /// The client area is the content of the window, excluding the title bar and borders.
472    ///
473    /// ## Platform-specific
474    ///
475    /// - **iOS:** Can only be called on the main thread. Returns the `PhysicalSize` of the window's
476    ///   [safe area] in screen space coordinates.
477    /// - **Web:** Returns the size of the canvas element.
478    ///
479    /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
480    #[inline]
481    pub fn inner_size(&self) -> PhysicalSize<u32> {
482        self.window.inner_size()
483    }
484
485    /// Modifies the inner size of the window.
486    ///
487    /// See `inner_size` for more information about the values. This automatically un-maximizes the
488    /// window if it's maximized.
489    ///
490    /// ## Platform-specific
491    ///
492    /// - **iOS / Android:** Unsupported.
493    /// - **Web:** Sets the size of the canvas element.
494    #[inline]
495    pub fn set_inner_size<S: Into<Size>>(&self, size: S) {
496        self.window.set_inner_size(size.into())
497    }
498
499    /// Returns the physical size of the entire window.
500    ///
501    /// These dimensions include the title bar and borders. If you don't want that (and you usually don't),
502    /// use `inner_size` instead.
503    ///
504    /// ## Platform-specific
505    ///
506    /// - **iOS:** Can only be called on the main thread. Returns the `PhysicalSize` of the window in
507    ///   screen space coordinates.
508    /// - **Web:** Returns the size of the canvas element. _Note: this returns the same value as
509    ///   `inner_size`._
510    #[inline]
511    pub fn outer_size(&self) -> PhysicalSize<u32> {
512        self.window.outer_size()
513    }
514
515    /// Sets a minimum dimension size for the window.
516    ///
517    /// ## Platform-specific
518    ///
519    /// - **iOS / Android / Web:** Unsupported.
520    #[inline]
521    pub fn set_min_inner_size<S: Into<Size>>(&self, min_size: Option<S>) {
522        self.window.set_min_inner_size(min_size.map(|s| s.into()))
523    }
524
525    /// Sets a maximum dimension size for the window.
526    ///
527    /// ## Platform-specific
528    ///
529    /// - **iOS / Andraid / Web:** Unsupported.
530    #[inline]
531    pub fn set_max_inner_size<S: Into<Size>>(&self, max_size: Option<S>) {
532        self.window.set_max_inner_size(max_size.map(|s| s.into()))
533    }
534}
535
536/// Misc. attribute functions.
537impl Window {
538    /// Modifies the title of the window.
539    ///
540    /// ## Platform-specific
541    ///
542    /// - **iOS / Android:** Unsupported.
543    #[inline]
544    pub fn set_title(&self, title: &str) {
545        self.window.set_title(title)
546    }
547
548    /// Modifies the window's visibility.
549    ///
550    /// If `false`, this will hide the window. If `true`, this will show the window.
551    /// ## Platform-specific
552    ///
553    /// - **Android / Wayland / Web:** Unsupported.
554    /// - **iOS:** Can only be called on the main thread.
555    #[inline]
556    pub fn set_visible(&self, visible: bool) {
557        self.window.set_visible(visible)
558    }
559
560    /// Sets whether the window is resizable or not.
561    ///
562    /// Note that making the window unresizable doesn't exempt you from handling `Resized`, as that event can still be
563    /// triggered by DPI scaling, entering fullscreen mode, etc.
564    ///
565    /// ## Platform-specific
566    ///
567    /// This only has an effect on desktop platforms.
568    ///
569    /// Due to a bug in XFCE, this has no effect on Xfwm.
570    ///
571    /// ## Platform-specific
572    ///
573    /// - **iOS / Android / Web:** Unsupported.
574    #[inline]
575    pub fn set_resizable(&self, resizable: bool) {
576        self.window.set_resizable(resizable)
577    }
578
579    /// Sets the window to minimized or back
580    ///
581    /// ## Platform-specific
582    ///
583    /// - **iOS / Android / Web:** Unsupported.
584    /// - **Wayland:** Un-minimize is unsupported.
585    #[inline]
586    pub fn set_minimized(&self, minimized: bool) {
587        self.window.set_minimized(minimized);
588    }
589
590    /// Sets the window to maximized or back.
591    ///
592    /// ## Platform-specific
593    ///
594    /// - **iOS / Android / Web:** Unsupported.
595    #[inline]
596    pub fn set_maximized(&self, maximized: bool) {
597        self.window.set_maximized(maximized)
598    }
599
600    /// Sets the window to fullscreen or back.
601    ///
602    /// ## Platform-specific
603    ///
604    /// - **macOS:** `Fullscreen::Exclusive` provides true exclusive mode with a
605    ///   video mode change. *Caveat!* macOS doesn't provide task switching (or
606    ///   spaces!) while in exclusive fullscreen mode. This mode should be used
607    ///   when a video mode change is desired, but for a better user experience,
608    ///   borderless fullscreen might be preferred.
609    ///
610    ///   `Fullscreen::Borderless` provides a borderless fullscreen window on a
611    ///   separate space. This is the idiomatic way for fullscreen games to work
612    ///   on macOS. See `WindowExtMacOs::set_simple_fullscreen` if
613    ///   separate spaces are not preferred.
614    ///
615    ///   The dock and the menu bar are always disabled in fullscreen mode.
616    /// - **iOS:** Can only be called on the main thread.
617    /// - **Wayland:** Does not support exclusive fullscreen mode.
618    /// - **Windows:** Screen saver is disabled in fullscreen mode.
619    /// - **Android:** Unsupported.
620    #[inline]
621    pub fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
622        self.window.set_fullscreen(fullscreen)
623    }
624
625    /// Gets the window's current fullscreen state.
626    ///
627    /// ## Platform-specific
628    ///
629    /// - **iOS:** Can only be called on the main thread.
630    /// - **Android:** Will always return `None`.
631    #[inline]
632    pub fn fullscreen(&self) -> Option<Fullscreen> {
633        self.window.fullscreen()
634    }
635
636    /// Turn window decorations on or off.
637    ///
638    /// ## Platform-specific
639    ///
640    /// - **iOS / Android / Web:** Unsupported.
641    ///
642    /// [`setPrefersStatusBarHidden`]: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc
643    #[inline]
644    pub fn set_decorations(&self, decorations: bool) {
645        self.window.set_decorations(decorations)
646    }
647
648    /// Change whether or not the window will always be on top of other windows.
649    ///
650    /// ## Platform-specific
651    ///
652    /// - **iOS / Android / Web / Wayland:** Unsupported.
653    #[inline]
654    pub fn set_always_on_top(&self, always_on_top: bool) {
655        self.window.set_always_on_top(always_on_top)
656    }
657
658    /// Sets the window icon. On Windows and X11, this is typically the small icon in the top-left
659    /// corner of the titlebar.
660    ///
661    /// ## Platform-specific
662    ///
663    /// - **iOS / Android / Web / Wayland / macOS:** Unsupported.
664    ///
665    /// On Windows, this sets `ICON_SMALL`. The base size for a window icon is 16x16, but it's
666    /// recommended to account for screen scaling and pick a multiple of that, i.e. 32x32.
667    ///
668    /// X11 has no universal guidelines for icon sizes, so you're at the whims of the WM. That
669    /// said, it's usually in the same ballpark as on Windows.
670    #[inline]
671    pub fn set_window_icon(&self, window_icon: Option<Icon>) {
672        self.window.set_window_icon(window_icon)
673    }
674
675    /// Sets location of IME candidate box in client area coordinates relative to the top left.
676    ///
677    /// ## Platform-specific
678    ///
679    /// - **iOS / Android / Web / Wayland / Windows:** Unsupported.
680    #[inline]
681    pub fn set_ime_position<P: Into<Position>>(&self, position: P) {
682        self.window.set_ime_position(position.into())
683    }
684}
685
686/// Cursor functions.
687impl Window {
688    /// Modifies the cursor icon of the window.
689    ///
690    /// ## Platform-specific
691    ///
692    /// - **iOS / Android:** Unsupported.
693    #[inline]
694    pub fn set_cursor_icon(&self, cursor: CursorIcon) {
695        self.window.set_cursor_icon(cursor);
696    }
697
698    /// Changes the position of the cursor in window coordinates.
699    ///
700    /// ## Platform-specific
701    ///
702    /// - **iOS / Android / Web / Wayland:** Always returns an [`ExternalError::NotSupported`].
703    #[inline]
704    pub fn set_cursor_position<P: Into<Position>>(&self, position: P) -> Result<(), ExternalError> {
705        self.window.set_cursor_position(position.into())
706    }
707
708    /// Grabs the cursor, preventing it from leaving the window.
709    ///
710    /// ## Platform-specific
711    ///
712    /// - **macOS / Wayland:** This locks the cursor in a fixed location, which looks visually awkward.
713    /// - **iOS / Android / Web:** Always returns an [`ExternalError::NotSupported`].
714    #[inline]
715    pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
716        self.window.set_cursor_grab(grab)
717    }
718
719    /// Modifies the cursor's visibility.
720    ///
721    /// If `false`, this will hide the cursor. If `true`, this will show the cursor.
722    ///
723    /// ## Platform-specific
724    ///
725    /// - **Windows:** The cursor is only hidden within the confines of the window.
726    /// - **X11:** The cursor is only hidden within the confines of the window.
727    /// - **Wayland:** The cursor is only hidden within the confines of the window.
728    /// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is
729    ///   outside of the window.
730    /// - **iOS / Android:** Unsupported.
731    #[inline]
732    pub fn set_cursor_visible(&self, visible: bool) {
733        self.window.set_cursor_visible(visible)
734    }
735}
736
737/// Monitor info functions.
738impl Window {
739    /// Returns the monitor on which the window currently resides
740    ///
741    /// ## Platform-specific
742    ///
743    /// **iOS:** Can only be called on the main thread.
744    #[inline]
745    pub fn current_monitor(&self) -> MonitorHandle {
746        self.window.current_monitor()
747    }
748
749    /// Returns the list of all the monitors available on the system.
750    ///
751    /// This is the same as `EventLoopWindowTarget::available_monitors`, and is provided for convenience.
752    ///
753    /// ## Platform-specific
754    ///
755    /// **iOS:** Can only be called on the main thread.
756    #[inline]
757    pub fn available_monitors(&self) -> impl Iterator<Item = MonitorHandle> {
758        self.window
759            .available_monitors()
760            .into_iter()
761            .map(|inner| MonitorHandle { inner })
762    }
763
764    /// Returns the primary monitor of the system.
765    ///
766    /// This is the same as `EventLoopWindowTarget::primary_monitor`, and is provided for convenience.
767    ///
768    /// ## Platform-specific
769    ///
770    /// **iOS:** Can only be called on the main thread.
771    #[inline]
772    pub fn primary_monitor(&self) -> MonitorHandle {
773        MonitorHandle {
774            inner: self.window.primary_monitor(),
775        }
776    }
777}
778
779unsafe impl raw_window_handle::HasRawWindowHandle for Window {
780    fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
781        self.window.raw_window_handle()
782    }
783}
784
785/// Describes the appearance of the mouse cursor.
786#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
787#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
788pub enum CursorIcon {
789    /// The platform-dependent default cursor.
790    Default,
791    /// A simple crosshair.
792    Crosshair,
793    /// A hand (often used to indicate links in web browsers).
794    Hand,
795    /// Self explanatory.
796    Arrow,
797    /// Indicates something is to be moved.
798    Move,
799    /// Indicates text that may be selected or edited.
800    Text,
801    /// Program busy indicator.
802    Wait,
803    /// Help indicator (often rendered as a "?")
804    Help,
805    /// Progress indicator. Shows that processing is being done. But in contrast
806    /// with "Wait" the user may still interact with the program. Often rendered
807    /// as a spinning beach ball, or an arrow with a watch or hourglass.
808    Progress,
809
810    /// Cursor showing that something cannot be done.
811    NotAllowed,
812    ContextMenu,
813    Cell,
814    VerticalText,
815    Alias,
816    Copy,
817    NoDrop,
818    /// Indicates something can be grabbed.
819    Grab,
820    /// Indicates something is grabbed.
821    Grabbing,
822    AllScroll,
823    ZoomIn,
824    ZoomOut,
825
826    /// Indicate that some edge is to be moved. For example, the 'SeResize' cursor
827    /// is used when the movement starts from the south-east corner of the box.
828    EResize,
829    NResize,
830    NeResize,
831    NwResize,
832    SResize,
833    SeResize,
834    SwResize,
835    WResize,
836    EwResize,
837    NsResize,
838    NeswResize,
839    NwseResize,
840    ColResize,
841    RowResize,
842}
843
844impl Default for CursorIcon {
845    fn default() -> Self {
846        CursorIcon::Default
847    }
848}
849
850#[derive(Clone, Debug, PartialEq)]
851pub enum Fullscreen {
852    Exclusive(VideoMode),
853    Borderless(MonitorHandle),
854}
855
856#[derive(Clone, Debug, PartialEq)]
857pub enum Theme {
858    Light,
859    Dark,
860}