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    /// The desired position of the window. If this is `None`, some platform-specific position
120    /// will be chosen.
121    ///
122    /// The default is `None`.
123    ///
124    /// ## Platform-specific
125    ///
126    /// - **macOS**: The top left corner position of the window content, the window's "inner"
127    /// position. The window title bar will be placed above it.
128    /// The window will be positioned such that it fits on screen, maintaining
129    /// set `inner_size` if any.
130    /// If you need to precisely position the top left corner of the whole window you have to
131    /// use [`Window::set_outer_position`] after creating the window.
132    /// - **Windows**: The top left corner position of the window title bar, the window's "outer"
133    /// position.
134    /// There may be a small gap between this position and the window due to the specifics of the
135    /// Window Manager.
136    /// - **X11**: The top left corner of the window, the window's "outer" position.
137    /// - **Others**: Ignored.
138    ///
139    /// See [`Window::set_outer_position`].
140    ///
141    /// [`Window::set_outer_position`]: crate::window::Window::set_outer_position
142    pub position: Option<Position>,
143
144    /// Whether the window is resizable or not.
145    ///
146    /// The default is `true`.
147    pub resizable: bool,
148
149    /// Whether the window should be set as fullscreen upon creation.
150    ///
151    /// The default is `None`.
152    pub fullscreen: Option<Fullscreen>,
153
154    /// The title of the window in the title bar.
155    ///
156    /// The default is `"winit window"`.
157    pub title: String,
158
159    /// Whether the window should be maximized upon creation.
160    ///
161    /// The default is `false`.
162    pub maximized: bool,
163
164    /// Whether the window should be immediately visible upon creation.
165    ///
166    /// The default is `true`.
167    pub visible: bool,
168
169    /// Whether the the window should be transparent. If this is true, writing colors
170    /// with alpha values different than `1.0` will produce a transparent window.
171    ///
172    /// The default is `false`.
173    pub transparent: bool,
174
175    /// Whether the window should have borders and bars.
176    ///
177    /// The default is `true`.
178    pub decorations: bool,
179
180    /// Whether the window should always be on top of other windows.
181    ///
182    /// The default is `false`.
183    pub always_on_top: bool,
184
185    /// The window icon.
186    ///
187    /// The default is `None`.
188    pub window_icon: Option<Icon>,
189}
190
191impl Default for WindowAttributes {
192    #[inline]
193    fn default() -> WindowAttributes {
194        WindowAttributes {
195            inner_size: None,
196            min_inner_size: None,
197            max_inner_size: None,
198            position: None,
199            resizable: true,
200            title: "winit window".to_owned(),
201            maximized: false,
202            fullscreen: None,
203            visible: true,
204            transparent: false,
205            decorations: true,
206            always_on_top: false,
207            window_icon: None,
208        }
209    }
210}
211
212impl WindowBuilder {
213    /// Initializes a new `WindowBuilder` with default values.
214    #[inline]
215    pub fn new() -> Self {
216        Default::default()
217    }
218
219    /// Requests the window to be of specific dimensions.
220    ///
221    /// See [`Window::set_inner_size`] for details.
222    ///
223    /// [`Window::set_inner_size`]: crate::window::Window::set_inner_size
224    #[inline]
225    pub fn with_inner_size<S: Into<Size>>(mut self, size: S) -> Self {
226        self.window.inner_size = Some(size.into());
227        self
228    }
229
230    /// Sets a minimum dimension size for the window.
231    ///
232    /// See [`Window::set_min_inner_size`] for details.
233    ///
234    /// [`Window::set_min_inner_size`]: crate::window::Window::set_min_inner_size
235    #[inline]
236    pub fn with_min_inner_size<S: Into<Size>>(mut self, min_size: S) -> Self {
237        self.window.min_inner_size = Some(min_size.into());
238        self
239    }
240
241    /// Sets a maximum dimension size for the window.
242    ///
243    /// See [`Window::set_max_inner_size`] for details.
244    ///
245    /// [`Window::set_max_inner_size`]: crate::window::Window::set_max_inner_size
246    #[inline]
247    pub fn with_max_inner_size<S: Into<Size>>(mut self, max_size: S) -> Self {
248        self.window.max_inner_size = Some(max_size.into());
249        self
250    }
251
252    /// Sets a desired initial position for the window.
253    ///
254    /// See [`WindowAttributes::position`] for details.
255    ///
256    /// [`WindowAttributes::position`]: crate::window::WindowAttributes::position
257    #[inline]
258    pub fn with_position<P: Into<Position>>(mut self, position: P) -> Self {
259        self.window.position = Some(position.into());
260        self
261    }
262
263    /// Sets whether the window is resizable or not.
264    ///
265    /// See [`Window::set_resizable`] for details.
266    ///
267    /// [`Window::set_resizable`]: crate::window::Window::set_resizable
268    #[inline]
269    pub fn with_resizable(mut self, resizable: bool) -> Self {
270        self.window.resizable = resizable;
271        self
272    }
273
274    /// Requests a specific title for the window.
275    ///
276    /// See [`Window::set_title`] for details.
277    ///
278    /// [`Window::set_title`]: crate::window::Window::set_title
279    #[inline]
280    pub fn with_title<T: Into<String>>(mut self, title: T) -> Self {
281        self.window.title = title.into();
282        self
283    }
284
285    /// Sets the window fullscreen state.
286    ///
287    /// See [`Window::set_fullscreen`] for details.
288    ///
289    /// [`Window::set_fullscreen`]: crate::window::Window::set_fullscreen
290    #[inline]
291    pub fn with_fullscreen(mut self, fullscreen: Option<Fullscreen>) -> Self {
292        self.window.fullscreen = fullscreen;
293        self
294    }
295
296    /// Requests maximized mode.
297    ///
298    /// See [`Window::set_maximized`] for details.
299    ///
300    /// [`Window::set_maximized`]: crate::window::Window::set_maximized
301    #[inline]
302    pub fn with_maximized(mut self, maximized: bool) -> Self {
303        self.window.maximized = maximized;
304        self
305    }
306
307    /// Sets whether the window will be initially hidden or visible.
308    ///
309    /// See [`Window::set_visible`] for details.
310    ///
311    /// [`Window::set_visible`]: crate::window::Window::set_visible
312    #[inline]
313    pub fn with_visible(mut self, visible: bool) -> Self {
314        self.window.visible = visible;
315        self
316    }
317
318    /// Sets whether the background of the window should be transparent.
319    #[inline]
320    pub fn with_transparent(mut self, transparent: bool) -> Self {
321        self.window.transparent = transparent;
322        self
323    }
324
325    /// Sets whether the window should have a border, a title bar, etc.
326    ///
327    /// See [`Window::set_decorations`] for details.
328    ///
329    /// [`Window::set_decorations`]: crate::window::Window::set_decorations
330    #[inline]
331    pub fn with_decorations(mut self, decorations: bool) -> Self {
332        self.window.decorations = decorations;
333        self
334    }
335
336    /// Sets whether or not the window will always be on top of other windows.
337    ///
338    /// See [`Window::set_always_on_top`] for details.
339    ///
340    /// [`Window::set_always_on_top`]: crate::window::Window::set_always_on_top
341    #[inline]
342    pub fn with_always_on_top(mut self, always_on_top: bool) -> Self {
343        self.window.always_on_top = always_on_top;
344        self
345    }
346
347    /// Sets the window icon.
348    ///
349    /// See [`Window::set_window_icon`] for details.
350    ///
351    /// [`Window::set_window_icon`]: crate::window::Window::set_window_icon
352    #[inline]
353    pub fn with_window_icon(mut self, window_icon: Option<Icon>) -> Self {
354        self.window.window_icon = window_icon;
355        self
356    }
357
358    /// Builds the window.
359    ///
360    /// Possible causes of error include denied permission, incompatible system, and lack of memory.
361    ///
362    /// Platform-specific behavior:
363    /// - **Web**: The window is created but not inserted into the web page automatically. Please
364    /// see the web platform module for more information.
365    #[inline]
366    pub fn build<T: 'static>(
367        self,
368        window_target: &EventLoopWindowTarget<T>,
369    ) -> Result<Window, OsError> {
370        platform_impl::Window::new(&window_target.p, self.window, self.platform_specific).map(
371            |window| {
372                window.request_redraw();
373                Window { window }
374            },
375        )
376    }
377}
378
379/// Base Window functions.
380impl Window {
381    /// Creates a new Window for platforms where this is appropriate.
382    ///
383    /// This function is equivalent to [`WindowBuilder::new().build(event_loop)`].
384    ///
385    /// Error should be very rare and only occur in case of permission denied, incompatible system,
386    ///  out of memory, etc.
387    ///
388    /// Platform-specific behavior:
389    /// - **Web**: The window is created but not inserted into the web page automatically. Please
390    /// see the web platform module for more information.
391    ///
392    /// [`WindowBuilder::new().build(event_loop)`]: crate::window::WindowBuilder::build
393    #[inline]
394    pub fn new<T: 'static>(event_loop: &EventLoopWindowTarget<T>) -> Result<Window, OsError> {
395        let builder = WindowBuilder::new();
396        builder.build(event_loop)
397    }
398
399    /// Returns an identifier unique to the window.
400    #[inline]
401    pub fn id(&self) -> WindowId {
402        WindowId(self.window.id())
403    }
404
405    /// Returns the scale factor that can be used to map logical pixels to physical pixels, and vice versa.
406    ///
407    /// See the [`dpi`](crate::dpi) module for more information.
408    ///
409    /// Note that this value can change depending on user action (for example if the window is
410    /// moved to another screen); as such, tracking `WindowEvent::ScaleFactorChanged` events is
411    /// the most robust way to track the DPI you need to use to draw.
412    ///
413    /// ## Platform-specific
414    ///
415    /// - **X11:** This respects Xft.dpi, and can be overridden using the `WINIT_X11_SCALE_FACTOR` environment variable.
416    /// - **Android:** Always returns 1.0.
417    /// - **iOS:** Can only be called on the main thread. Returns the underlying `UIView`'s
418    ///   [`contentScaleFactor`].
419    ///
420    /// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
421    #[inline]
422    pub fn scale_factor(&self) -> f64 {
423        self.window.scale_factor()
424    }
425
426    /// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS
427    /// events have been processed by the event loop.
428    ///
429    /// This is the **strongly encouraged** method of redrawing windows, as it can integrate with
430    /// OS-requested redraws (e.g. when a window gets resized).
431    ///
432    /// This function can cause `RedrawRequested` events to be emitted after `Event::MainEventsCleared`
433    /// but before `Event::NewEvents` if called in the following circumstances:
434    /// * While processing `MainEventsCleared`.
435    /// * While processing a `RedrawRequested` event that was sent during `MainEventsCleared` or any
436    ///   directly subsequent `RedrawRequested` event.
437    ///
438    /// ## Platform-specific
439    ///
440    /// - **iOS:** Can only be called on the main thread.
441    /// - **Android:** Unsupported.
442    #[inline]
443    pub fn request_redraw(&self) {
444        self.window.request_redraw()
445    }
446}
447
448/// Position and size functions.
449impl Window {
450    /// Returns the position of the top-left hand corner of the window's client area relative to the
451    /// top-left hand corner of the desktop.
452    ///
453    /// The same conditions that apply to `outer_position` apply to this method.
454    ///
455    /// ## Platform-specific
456    ///
457    /// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
458    ///   window's [safe area] in the screen space coordinate system.
459    /// - **Web:** Returns the top-left coordinates relative to the viewport. _Note: this returns the
460    ///    same value as `outer_position`._
461    /// - **Android / Wayland:** Always returns [`NotSupportedError`].
462    ///
463    /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
464    #[inline]
465    pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
466        self.window.inner_position()
467    }
468
469    /// Returns the position of the top-left hand corner of the window relative to the
470    ///  top-left hand corner of the desktop.
471    ///
472    /// Note that the top-left hand corner of the desktop is not necessarily the same as
473    ///  the screen. If the user uses a desktop with multiple monitors, the top-left hand corner
474    ///  of the desktop is the top-left hand corner of the monitor at the top-left of the desktop.
475    ///
476    /// The coordinates can be negative if the top-left hand corner of the window is outside
477    ///  of the visible screen region.
478    ///
479    /// ## Platform-specific
480    ///
481    /// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
482    ///   window in the screen space coordinate system.
483    /// - **Web:** Returns the top-left coordinates relative to the viewport.
484    /// - **Android / Wayland:** Always returns [`NotSupportedError`].
485    #[inline]
486    pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
487        self.window.outer_position()
488    }
489
490    /// Modifies the position of the window.
491    ///
492    /// See `outer_position` for more information about the coordinates. This automatically un-maximizes the
493    /// window if it's maximized.
494    ///
495    /// ## Platform-specific
496    ///
497    /// - **iOS:** Can only be called on the main thread. Sets the top left coordinates of the
498    ///   window in the screen space coordinate system.
499    /// - **Web:** Sets the top-left coordinates relative to the viewport.
500    /// - **Android / Wayland:** Unsupported.
501    #[inline]
502    pub fn set_outer_position<P: Into<Position>>(&self, position: P) {
503        self.window.set_outer_position(position.into())
504    }
505
506    /// Returns the physical size of the window's client area.
507    ///
508    /// The client area is the content of the window, excluding the title bar and borders.
509    ///
510    /// ## Platform-specific
511    ///
512    /// - **iOS:** Can only be called on the main thread. Returns the `PhysicalSize` of the window's
513    ///   [safe area] in screen space coordinates.
514    /// - **Web:** Returns the size of the canvas element.
515    ///
516    /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
517    #[inline]
518    pub fn inner_size(&self) -> PhysicalSize<u32> {
519        self.window.inner_size()
520    }
521
522    /// Modifies the inner size of the window.
523    ///
524    /// See `inner_size` for more information about the values. This automatically un-maximizes the
525    /// window if it's maximized.
526    ///
527    /// ## Platform-specific
528    ///
529    /// - **iOS / Android:** Unsupported.
530    /// - **Web:** Sets the size of the canvas element.
531    #[inline]
532    pub fn set_inner_size<S: Into<Size>>(&self, size: S) {
533        self.window.set_inner_size(size.into())
534    }
535
536    /// Returns the physical size of the entire window.
537    ///
538    /// These dimensions include the title bar and borders. If you don't want that (and you usually don't),
539    /// use `inner_size` instead.
540    ///
541    /// ## Platform-specific
542    ///
543    /// - **iOS:** Can only be called on the main thread. Returns the `PhysicalSize` of the window in
544    ///   screen space coordinates.
545    /// - **Web:** Returns the size of the canvas element. _Note: this returns the same value as
546    ///   `inner_size`._
547    #[inline]
548    pub fn outer_size(&self) -> PhysicalSize<u32> {
549        self.window.outer_size()
550    }
551
552    /// Sets a minimum dimension size for the window.
553    ///
554    /// ## Platform-specific
555    ///
556    /// - **iOS / Android / Web:** Unsupported.
557    #[inline]
558    pub fn set_min_inner_size<S: Into<Size>>(&self, min_size: Option<S>) {
559        self.window.set_min_inner_size(min_size.map(|s| s.into()))
560    }
561
562    /// Sets a maximum dimension size for the window.
563    ///
564    /// ## Platform-specific
565    ///
566    /// - **iOS / Android / Web:** Unsupported.
567    #[inline]
568    pub fn set_max_inner_size<S: Into<Size>>(&self, max_size: Option<S>) {
569        self.window.set_max_inner_size(max_size.map(|s| s.into()))
570    }
571}
572
573/// Misc. attribute functions.
574impl Window {
575    /// Modifies the title of the window.
576    ///
577    /// ## Platform-specific
578    ///
579    /// - **iOS / Android:** Unsupported.
580    #[inline]
581    pub fn set_title(&self, title: &str) {
582        self.window.set_title(title)
583    }
584
585    /// Modifies the window's visibility.
586    ///
587    /// If `false`, this will hide the window. If `true`, this will show the window.
588    /// ## Platform-specific
589    ///
590    /// - **Android / Wayland / Web:** Unsupported.
591    /// - **iOS:** Can only be called on the main thread.
592    #[inline]
593    pub fn set_visible(&self, visible: bool) {
594        self.window.set_visible(visible)
595    }
596
597    /// Sets whether the window is resizable or not.
598    ///
599    /// Note that making the window unresizable doesn't exempt you from handling `Resized`, as that event can still be
600    /// triggered by DPI scaling, entering fullscreen mode, etc.
601    ///
602    /// ## Platform-specific
603    ///
604    /// This only has an effect on desktop platforms.
605    ///
606    /// Due to a bug in XFCE, this has no effect on Xfwm.
607    ///
608    /// ## Platform-specific
609    ///
610    /// - **iOS / Android / Web:** Unsupported.
611    #[inline]
612    pub fn set_resizable(&self, resizable: bool) {
613        self.window.set_resizable(resizable)
614    }
615
616    /// Sets the window to minimized or back
617    ///
618    /// ## Platform-specific
619    ///
620    /// - **iOS / Android / Web:** Unsupported.
621    /// - **Wayland:** Un-minimize is unsupported.
622    #[inline]
623    pub fn set_minimized(&self, minimized: bool) {
624        self.window.set_minimized(minimized);
625    }
626
627    /// Sets the window to maximized or back.
628    ///
629    /// ## Platform-specific
630    ///
631    /// - **iOS / Android / Web:** Unsupported.
632    #[inline]
633    pub fn set_maximized(&self, maximized: bool) {
634        self.window.set_maximized(maximized)
635    }
636
637    /// Gets the window's current maximized state.
638    ///
639    /// ## Platform-specific
640    ///
641    /// - **Wayland / X11:** Not implemented.
642    /// - **iOS / Android / Web:** Unsupported.
643    #[inline]
644    pub fn is_maximized(&self) -> bool {
645        self.window.is_maximized()
646    }
647
648    /// Sets the window to fullscreen or back.
649    ///
650    /// ## Platform-specific
651    ///
652    /// - **macOS:** `Fullscreen::Exclusive` provides true exclusive mode with a
653    ///   video mode change. *Caveat!* macOS doesn't provide task switching (or
654    ///   spaces!) while in exclusive fullscreen mode. This mode should be used
655    ///   when a video mode change is desired, but for a better user experience,
656    ///   borderless fullscreen might be preferred.
657    ///
658    ///   `Fullscreen::Borderless` provides a borderless fullscreen window on a
659    ///   separate space. This is the idiomatic way for fullscreen games to work
660    ///   on macOS. See `WindowExtMacOs::set_simple_fullscreen` if
661    ///   separate spaces are not preferred.
662    ///
663    ///   The dock and the menu bar are always disabled in fullscreen mode.
664    /// - **iOS:** Can only be called on the main thread.
665    /// - **Wayland:** Does not support exclusive fullscreen mode and will no-op a request.
666    /// - **Windows:** Screen saver is disabled in fullscreen mode.
667    /// - **Android:** Unsupported.
668    #[inline]
669    pub fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
670        self.window.set_fullscreen(fullscreen)
671    }
672
673    /// Gets the window's current fullscreen state.
674    ///
675    /// ## Platform-specific
676    ///
677    /// - **iOS:** Can only be called on the main thread.
678    /// - **Android:** Will always return `None`.
679    /// - **Wayland:** Can return `Borderless(None)` when there are no monitors.
680    #[inline]
681    pub fn fullscreen(&self) -> Option<Fullscreen> {
682        self.window.fullscreen()
683    }
684
685    /// Turn window decorations on or off.
686    ///
687    /// ## Platform-specific
688    ///
689    /// - **iOS / Android / Web:** Unsupported.
690    ///
691    /// [`setPrefersStatusBarHidden`]: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc
692    #[inline]
693    pub fn set_decorations(&self, decorations: bool) {
694        self.window.set_decorations(decorations)
695    }
696
697    /// Change whether or not the window will always be on top of other windows.
698    ///
699    /// ## Platform-specific
700    ///
701    /// - **iOS / Android / Web / Wayland:** Unsupported.
702    #[inline]
703    pub fn set_always_on_top(&self, always_on_top: bool) {
704        self.window.set_always_on_top(always_on_top)
705    }
706
707    /// Sets the window icon. On Windows and X11, this is typically the small icon in the top-left
708    /// corner of the titlebar.
709    ///
710    /// ## Platform-specific
711    ///
712    /// - **iOS / Android / Web / Wayland / macOS:** Unsupported.
713    ///
714    /// On Windows, this sets `ICON_SMALL`. The base size for a window icon is 16x16, but it's
715    /// recommended to account for screen scaling and pick a multiple of that, i.e. 32x32.
716    ///
717    /// X11 has no universal guidelines for icon sizes, so you're at the whims of the WM. That
718    /// said, it's usually in the same ballpark as on Windows.
719    #[inline]
720    pub fn set_window_icon(&self, window_icon: Option<Icon>) {
721        self.window.set_window_icon(window_icon)
722    }
723
724    /// Sets location of IME candidate box in client area coordinates relative to the top left.
725    ///
726    /// ## Platform-specific
727    ///
728    /// - **iOS / Android / Web:** Unsupported.
729    #[inline]
730    pub fn set_ime_position<P: Into<Position>>(&self, position: P) {
731        self.window.set_ime_position(position.into())
732    }
733
734    /// Requests user attention to the window, this has no effect if the application
735    /// is already focused. How requesting for user attention manifests is platform dependent,
736    /// see `UserAttentionType` for details.
737    ///
738    /// Providing `None` will unset the request for user attention. Unsetting the request for
739    /// user attention might not be done automatically by the WM when the window receives input.
740    ///
741    /// ## Platform-specific
742    ///
743    /// - **iOS / Android / Web / Wayland:** Unsupported.
744    /// - **macOS:** `None` has no effect.
745    /// - **X11:** Requests for user attention must be manually cleared.
746    #[inline]
747    pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
748        self.window.request_user_attention(request_type)
749    }
750}
751
752/// Cursor functions.
753impl Window {
754    /// Modifies the cursor icon of the window.
755    ///
756    /// ## Platform-specific
757    ///
758    /// - **iOS / Android:** Unsupported.
759    #[inline]
760    pub fn set_cursor_icon(&self, cursor: CursorIcon) {
761        self.window.set_cursor_icon(cursor);
762    }
763
764    /// Changes the position of the cursor in window coordinates.
765    ///
766    /// ## Platform-specific
767    ///
768    /// - **iOS / Android / Web / Wayland:** Always returns an [`ExternalError::NotSupported`].
769    #[inline]
770    pub fn set_cursor_position<P: Into<Position>>(&self, position: P) -> Result<(), ExternalError> {
771        self.window.set_cursor_position(position.into())
772    }
773
774    /// Grabs the cursor, preventing it from leaving the window.
775    ///
776    /// There's no guarantee that the cursor will be hidden. You should
777    /// hide it by yourself if you want so.
778    ///
779    /// ## Platform-specific
780    ///
781    /// - **macOS:** This locks the cursor in a fixed location, which looks visually awkward.
782    /// - **iOS / Android / Web:** Always returns an [`ExternalError::NotSupported`].
783    #[inline]
784    pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
785        self.window.set_cursor_grab(grab)
786    }
787
788    /// Modifies the cursor's visibility.
789    ///
790    /// If `false`, this will hide the cursor. If `true`, this will show the cursor.
791    ///
792    /// ## Platform-specific
793    ///
794    /// - **Windows:** The cursor is only hidden within the confines of the window.
795    /// - **X11:** The cursor is only hidden within the confines of the window.
796    /// - **Wayland:** The cursor is only hidden within the confines of the window.
797    /// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is
798    ///   outside of the window.
799    /// - **iOS / Android:** Unsupported.
800    #[inline]
801    pub fn set_cursor_visible(&self, visible: bool) {
802        self.window.set_cursor_visible(visible)
803    }
804
805    /// Moves the window with the left mouse button until the button is released.
806    ///
807    /// There's no guarantee that this will work unless the left mouse button was pressed
808    /// immediately before this function is called.
809    ///
810    /// ## Platform-specific
811    ///
812    /// - **X11:** Un-grabs the cursor.
813    /// - **Wayland:** Requires the cursor to be inside the window to be dragged.
814    /// - **macOS:** May prevent the button release event to be triggered.
815    /// - **iOS / Android / Web:** Always returns an [`ExternalError::NotSupported`].
816    #[inline]
817    pub fn drag_window(&self) -> Result<(), ExternalError> {
818        self.window.drag_window()
819    }
820}
821
822/// Monitor info functions.
823impl Window {
824    /// Returns the monitor on which the window currently resides.
825    ///
826    /// Returns `None` if current monitor can't be detected.
827    ///
828    /// ## Platform-specific
829    ///
830    /// **iOS:** Can only be called on the main thread.
831    #[inline]
832    pub fn current_monitor(&self) -> Option<MonitorHandle> {
833        self.window.current_monitor()
834    }
835
836    /// Returns the list of all the monitors available on the system.
837    ///
838    /// This is the same as `EventLoopWindowTarget::available_monitors`, and is provided for convenience.
839    ///
840    /// ## Platform-specific
841    ///
842    /// **iOS:** Can only be called on the main thread.
843    #[inline]
844    pub fn available_monitors(&self) -> impl Iterator<Item = MonitorHandle> {
845        self.window
846            .available_monitors()
847            .into_iter()
848            .map(|inner| MonitorHandle { inner })
849    }
850
851    /// Returns the primary monitor of the system.
852    ///
853    /// Returns `None` if it can't identify any monitor as a primary one.
854    ///
855    /// This is the same as `EventLoopWindowTarget::primary_monitor`, and is provided for convenience.
856    ///
857    /// ## Platform-specific
858    ///
859    /// **iOS:** Can only be called on the main thread.
860    /// **Wayland:** Always returns `None`.
861    #[inline]
862    pub fn primary_monitor(&self) -> Option<MonitorHandle> {
863        self.window.primary_monitor()
864    }
865}
866
867unsafe impl raw_window_handle::HasRawWindowHandle for Window {
868    /// Returns a `raw_window_handle::RawWindowHandle` for the Window
869    ///
870    /// ## Platform-specific
871    ///
872    /// - **Android:** Only available after receiving the Resumed event and before Suspended. *If you*
873    /// *try to get the handle outside of that period, this function will panic*!
874    fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
875        self.window.raw_window_handle()
876    }
877}
878
879/// Describes the appearance of the mouse cursor.
880#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
881#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
882pub enum CursorIcon {
883    /// The platform-dependent default cursor.
884    Default,
885    /// A simple crosshair.
886    Crosshair,
887    /// A hand (often used to indicate links in web browsers).
888    Hand,
889    /// Self explanatory.
890    Arrow,
891    /// Indicates something is to be moved.
892    Move,
893    /// Indicates text that may be selected or edited.
894    Text,
895    /// Program busy indicator.
896    Wait,
897    /// Help indicator (often rendered as a "?")
898    Help,
899    /// Progress indicator. Shows that processing is being done. But in contrast
900    /// with "Wait" the user may still interact with the program. Often rendered
901    /// as a spinning beach ball, or an arrow with a watch or hourglass.
902    Progress,
903
904    /// Cursor showing that something cannot be done.
905    NotAllowed,
906    ContextMenu,
907    Cell,
908    VerticalText,
909    Alias,
910    Copy,
911    NoDrop,
912    /// Indicates something can be grabbed.
913    Grab,
914    /// Indicates something is grabbed.
915    Grabbing,
916    AllScroll,
917    ZoomIn,
918    ZoomOut,
919
920    /// Indicate that some edge is to be moved. For example, the 'SeResize' cursor
921    /// is used when the movement starts from the south-east corner of the box.
922    EResize,
923    NResize,
924    NeResize,
925    NwResize,
926    SResize,
927    SeResize,
928    SwResize,
929    WResize,
930    EwResize,
931    NsResize,
932    NeswResize,
933    NwseResize,
934    ColResize,
935    RowResize,
936}
937
938impl Default for CursorIcon {
939    fn default() -> Self {
940        CursorIcon::Default
941    }
942}
943
944/// Fullscreen modes.
945#[derive(Clone, Debug, PartialEq)]
946pub enum Fullscreen {
947    Exclusive(VideoMode),
948
949    /// Providing `None` to `Borderless` will fullscreen on the current monitor.
950    Borderless(Option<MonitorHandle>),
951}
952
953#[derive(Clone, Copy, Debug, PartialEq)]
954pub enum Theme {
955    Light,
956    Dark,
957}
958
959/// ## Platform-specific
960///
961/// - **X11:** Sets the WM's `XUrgencyHint`. No distinction between `Critical` and `Informational`.
962#[derive(Debug, Clone, Copy, PartialEq)]
963pub enum UserAttentionType {
964    /// ## Platform-specific
965    /// - **macOS:** Bounces the dock icon until the application is in focus.
966    /// - **Windows:** Flashes both the window and the taskbar button until the application is in focus.
967    Critical,
968    /// ## Platform-specific
969    /// - **macOS:** Bounces the dock icon once.
970    /// - **Windows:** Flashes the taskbar button until the application is in focus.
971    Informational,
972}
973
974impl Default for UserAttentionType {
975    fn default() -> Self {
976        UserAttentionType::Informational
977    }
978}