winit/
window.rs

1//! The [`Window`] struct and associated types.
2use std::fmt;
3
4#[doc(inline)]
5pub use cursor_icon::{CursorIcon, ParseError as CursorIconParseError};
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9pub use crate::cursor::{BadImage, Cursor, CustomCursor, CustomCursorSource, MAX_CURSOR_SIZE};
10use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
11use crate::error::RequestError;
12pub use crate::icon::{BadIcon, Icon};
13use crate::monitor::{MonitorHandle, VideoModeHandle};
14use crate::platform_impl::{self, PlatformSpecificWindowAttributes};
15use crate::utils::AsAny;
16
17/// Identifier of a window. Unique for each window.
18///
19/// Can be obtained with [`window.id()`][`Window::id`].
20///
21/// Whenever you receive an event specific to a window, this event contains a `WindowId` which you
22/// can then compare to the ids of your windows.
23#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub struct WindowId(pub(crate) platform_impl::WindowId);
25
26impl WindowId {
27    /// Returns a dummy id, useful for unit testing.
28    ///
29    /// # Notes
30    ///
31    /// The only guarantee made about the return value of this function is that
32    /// it will always be equal to itself and to future values returned by this function.
33    /// No other guarantees are made. This may be equal to a real [`WindowId`].
34    pub const fn dummy() -> Self {
35        WindowId(platform_impl::WindowId::dummy())
36    }
37}
38
39impl fmt::Debug for WindowId {
40    fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result {
41        self.0.fmt(fmtr)
42    }
43}
44
45impl From<WindowId> for u64 {
46    fn from(window_id: WindowId) -> Self {
47        window_id.0.into()
48    }
49}
50
51impl From<u64> for WindowId {
52    fn from(raw_id: u64) -> Self {
53        Self(raw_id.into())
54    }
55}
56
57/// Attributes used when creating a window.
58#[derive(Debug, Clone, PartialEq)]
59pub struct WindowAttributes {
60    pub surface_size: Option<Size>,
61    pub min_surface_size: Option<Size>,
62    pub max_surface_size: Option<Size>,
63    pub surface_resize_increments: Option<Size>,
64    pub position: Option<Position>,
65    pub resizable: bool,
66    pub enabled_buttons: WindowButtons,
67    pub title: String,
68    pub maximized: bool,
69    pub visible: bool,
70    pub transparent: bool,
71    pub blur: bool,
72    pub decorations: bool,
73    pub window_icon: Option<Icon>,
74    pub preferred_theme: Option<Theme>,
75    pub content_protected: bool,
76    pub window_level: WindowLevel,
77    pub active: bool,
78    pub cursor: Cursor,
79    #[cfg(feature = "rwh_06")]
80    pub(crate) parent_window: Option<SendSyncRawWindowHandle>,
81    pub fullscreen: Option<Fullscreen>,
82    // Platform-specific configuration.
83    #[allow(dead_code)]
84    pub(crate) platform_specific: PlatformSpecificWindowAttributes,
85}
86
87impl Default for WindowAttributes {
88    #[inline]
89    fn default() -> WindowAttributes {
90        WindowAttributes {
91            surface_size: None,
92            min_surface_size: None,
93            max_surface_size: None,
94            surface_resize_increments: None,
95            position: None,
96            resizable: true,
97            enabled_buttons: WindowButtons::all(),
98            title: "winit window".to_owned(),
99            maximized: false,
100            fullscreen: None,
101            visible: true,
102            transparent: false,
103            blur: false,
104            decorations: true,
105            window_level: Default::default(),
106            window_icon: None,
107            preferred_theme: None,
108            content_protected: false,
109            cursor: Cursor::default(),
110            #[cfg(feature = "rwh_06")]
111            parent_window: None,
112            active: true,
113            platform_specific: Default::default(),
114        }
115    }
116}
117
118/// Wrapper for [`rwh_06::RawWindowHandle`] for [`WindowAttributes::parent_window`].
119///
120/// # Safety
121///
122/// The user has to account for that when using [`WindowAttributes::with_parent_window()`],
123/// which is `unsafe`.
124#[derive(Debug, Clone, PartialEq)]
125#[cfg(feature = "rwh_06")]
126pub(crate) struct SendSyncRawWindowHandle(pub(crate) rwh_06::RawWindowHandle);
127
128#[cfg(feature = "rwh_06")]
129unsafe impl Send for SendSyncRawWindowHandle {}
130#[cfg(feature = "rwh_06")]
131unsafe impl Sync for SendSyncRawWindowHandle {}
132
133impl WindowAttributes {
134    /// Get the parent window stored on the attributes.
135    #[cfg(feature = "rwh_06")]
136    pub fn parent_window(&self) -> Option<&rwh_06::RawWindowHandle> {
137        self.parent_window.as_ref().map(|handle| &handle.0)
138    }
139
140    /// Requests the surface to be of specific dimensions.
141    ///
142    /// If this is not set, some platform-specific dimensions will be used.
143    ///
144    /// See [`Window::request_surface_size`] for details.
145    #[inline]
146    pub fn with_surface_size<S: Into<Size>>(mut self, size: S) -> Self {
147        self.surface_size = Some(size.into());
148        self
149    }
150
151    /// Sets the minimum dimensions the surface can have.
152    ///
153    /// If this is not set, the surface will have no minimum dimensions (aside from reserved).
154    ///
155    /// See [`Window::set_min_surface_size`] for details.
156    #[inline]
157    pub fn with_min_surface_size<S: Into<Size>>(mut self, min_size: S) -> Self {
158        self.min_surface_size = Some(min_size.into());
159        self
160    }
161
162    /// Sets the maximum dimensions the surface can have.
163    ///
164    /// If this is not set, the surface will have no maximum, or the maximum will be restricted to
165    /// the primary monitor's dimensions by the platform.
166    ///
167    /// See [`Window::set_max_surface_size`] for details.
168    #[inline]
169    pub fn with_max_surface_size<S: Into<Size>>(mut self, max_size: S) -> Self {
170        self.max_surface_size = Some(max_size.into());
171        self
172    }
173
174    /// Build window with resize increments hint.
175    ///
176    /// The default is `None`.
177    ///
178    /// See [`Window::set_surface_resize_increments`] for details.
179    #[inline]
180    pub fn with_surface_resize_increments<S: Into<Size>>(
181        mut self,
182        surface_resize_increments: S,
183    ) -> Self {
184        self.surface_resize_increments = Some(surface_resize_increments.into());
185        self
186    }
187
188    /// Sets a desired initial position for the window.
189    ///
190    /// If this is not set, some platform-specific position will be chosen.
191    ///
192    /// See [`Window::set_outer_position`] for details.
193    ///
194    /// ## Platform-specific
195    ///
196    /// - **macOS:** The top left corner position of the window content, the window's "inner"
197    ///   position. The window title bar will be placed above it. The window will be positioned such
198    ///   that it fits on screen, maintaining set `surface_size` if any. If you need to precisely
199    ///   position the top left corner of the whole window you have to use
200    ///   [`Window::set_outer_position`] after creating the window.
201    /// - **Windows:** The top left corner position of the window title bar, the window's "outer"
202    ///   position. There may be a small gap between this position and the window due to the
203    ///   specifics of the Window Manager.
204    /// - **X11:** The top left corner of the window, the window's "outer" position.
205    /// - **Others:** Ignored.
206    #[inline]
207    pub fn with_position<P: Into<Position>>(mut self, position: P) -> Self {
208        self.position = Some(position.into());
209        self
210    }
211
212    /// Sets whether the window is resizable or not.
213    ///
214    /// The default is `true`.
215    ///
216    /// See [`Window::set_resizable`] for details.
217    #[inline]
218    pub fn with_resizable(mut self, resizable: bool) -> Self {
219        self.resizable = resizable;
220        self
221    }
222
223    /// Sets the enabled window buttons.
224    ///
225    /// The default is [`WindowButtons::all`]
226    ///
227    /// See [`Window::set_enabled_buttons`] for details.
228    #[inline]
229    pub fn with_enabled_buttons(mut self, buttons: WindowButtons) -> Self {
230        self.enabled_buttons = buttons;
231        self
232    }
233
234    /// Sets the initial title of the window in the title bar.
235    ///
236    /// The default is `"winit window"`.
237    ///
238    /// See [`Window::set_title`] for details.
239    #[inline]
240    pub fn with_title<T: Into<String>>(mut self, title: T) -> Self {
241        self.title = title.into();
242        self
243    }
244
245    /// Sets whether the window should be put into fullscreen upon creation.
246    ///
247    /// The default is `None`.
248    ///
249    /// See [`Window::set_fullscreen`] for details.
250    #[inline]
251    pub fn with_fullscreen(mut self, fullscreen: Option<Fullscreen>) -> Self {
252        self.fullscreen = fullscreen;
253        self
254    }
255
256    /// Request that the window is maximized upon creation.
257    ///
258    /// The default is `false`.
259    ///
260    /// See [`Window::set_maximized`] for details.
261    #[inline]
262    pub fn with_maximized(mut self, maximized: bool) -> Self {
263        self.maximized = maximized;
264        self
265    }
266
267    /// Sets whether the window will be initially visible or hidden.
268    ///
269    /// The default is to show the window.
270    ///
271    /// See [`Window::set_visible`] for details.
272    #[inline]
273    pub fn with_visible(mut self, visible: bool) -> Self {
274        self.visible = visible;
275        self
276    }
277
278    /// Sets whether the background of the window should be transparent.
279    ///
280    /// If this is `true`, writing colors with alpha values different than
281    /// `1.0` will produce a transparent window. On some platforms this
282    /// is more of a hint for the system and you'd still have the alpha
283    /// buffer. To control it see [`Window::set_transparent`].
284    ///
285    /// The default is `false`.
286    #[inline]
287    pub fn with_transparent(mut self, transparent: bool) -> Self {
288        self.transparent = transparent;
289        self
290    }
291
292    /// Sets whether the background of the window should be blurred by the system.
293    ///
294    /// The default is `false`.
295    ///
296    /// See [`Window::set_blur`] for details.
297    #[inline]
298    pub fn with_blur(mut self, blur: bool) -> Self {
299        self.blur = blur;
300        self
301    }
302
303    /// Get whether the window will support transparency.
304    #[inline]
305    pub fn transparent(&self) -> bool {
306        self.transparent
307    }
308
309    /// Sets whether the window should have a border, a title bar, etc.
310    ///
311    /// The default is `true`.
312    ///
313    /// See [`Window::set_decorations`] for details.
314    #[inline]
315    pub fn with_decorations(mut self, decorations: bool) -> Self {
316        self.decorations = decorations;
317        self
318    }
319
320    /// Sets the window level.
321    ///
322    /// This is just a hint to the OS, and the system could ignore it.
323    ///
324    /// The default is [`WindowLevel::Normal`].
325    ///
326    /// See [`WindowLevel`] for details.
327    #[inline]
328    pub fn with_window_level(mut self, level: WindowLevel) -> Self {
329        self.window_level = level;
330        self
331    }
332
333    /// Sets the window icon.
334    ///
335    /// The default is `None`.
336    ///
337    /// See [`Window::set_window_icon`] for details.
338    #[inline]
339    pub fn with_window_icon(mut self, window_icon: Option<Icon>) -> Self {
340        self.window_icon = window_icon;
341        self
342    }
343
344    /// Sets a specific theme for the window.
345    ///
346    /// If `None` is provided, the window will use the system theme.
347    ///
348    /// The default is `None`.
349    ///
350    /// ## Platform-specific
351    ///
352    /// - **Wayland:** This controls only CSD. When using `None` it'll try to use dbus to get the
353    ///   system preference. When explicit theme is used, this will avoid dbus all together.
354    /// - **x11:** Build window with `_GTK_THEME_VARIANT` hint set to `dark` or `light`.
355    /// - **iOS / Android / Web / x11 / Orbital:** Ignored.
356    #[inline]
357    pub fn with_theme(mut self, theme: Option<Theme>) -> Self {
358        self.preferred_theme = theme;
359        self
360    }
361
362    /// Prevents the window contents from being captured by other apps.
363    ///
364    /// The default is `false`.
365    ///
366    /// ## Platform-specific
367    ///
368    /// - **macOS**: if `false`, [`NSWindowSharingNone`] is used but doesn't completely prevent all
369    ///   apps from reading the window content, for instance, QuickTime.
370    /// - **iOS / Android / Web / x11 / Orbital:** Ignored.
371    ///
372    /// [`NSWindowSharingNone`]: https://developer.apple.com/documentation/appkit/nswindowsharingtype/nswindowsharingnone
373    #[inline]
374    pub fn with_content_protected(mut self, protected: bool) -> Self {
375        self.content_protected = protected;
376        self
377    }
378
379    /// Whether the window will be initially focused or not.
380    ///
381    /// The window should be assumed as not focused by default
382    /// following by the [`WindowEvent::Focused`].
383    ///
384    /// ## Platform-specific:
385    ///
386    /// **Android / iOS / X11 / Wayland / Orbital:** Unsupported.
387    ///
388    /// [`WindowEvent::Focused`]: crate::event::WindowEvent::Focused.
389    #[inline]
390    pub fn with_active(mut self, active: bool) -> Self {
391        self.active = active;
392        self
393    }
394
395    /// Modifies the cursor icon of the window.
396    ///
397    /// The default is [`CursorIcon::Default`].
398    ///
399    /// See [`Window::set_cursor()`] for more details.
400    #[inline]
401    pub fn with_cursor(mut self, cursor: impl Into<Cursor>) -> Self {
402        self.cursor = cursor.into();
403        self
404    }
405
406    /// Build window with parent window.
407    ///
408    /// The default is `None`.
409    ///
410    /// ## Safety
411    ///
412    /// `parent_window` must be a valid window handle.
413    ///
414    /// ## Platform-specific
415    ///
416    /// - **Windows** : A child window has the WS_CHILD style and is confined
417    ///   to the client area of its parent window. For more information, see
418    ///   <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#child-windows>
419    /// - **X11**: A child window is confined to the client area of its parent window.
420    /// - **Android / iOS / Wayland / Web:** Unsupported.
421    #[cfg(feature = "rwh_06")]
422    #[inline]
423    pub unsafe fn with_parent_window(
424        mut self,
425        parent_window: Option<rwh_06::RawWindowHandle>,
426    ) -> Self {
427        self.parent_window = parent_window.map(SendSyncRawWindowHandle);
428        self
429    }
430}
431
432/// Represents a window.
433///
434/// The window is closed when dropped.
435///
436/// ## Threading
437///
438/// This is `Send + Sync`, meaning that it can be freely used from other
439/// threads.
440///
441/// However, some platforms (macOS, Web and iOS) only allow user interface
442/// interactions on the main thread, so on those platforms, if you use the
443/// window from a thread other than the main, the code is scheduled to run on
444/// the main thread, and your thread may be blocked until that completes.
445///
446/// ## Platform-specific
447///
448/// **Web:** The [`Window`], which is represented by a `HTMLElementCanvas`, can
449/// not be closed by dropping the [`Window`].
450pub trait Window: AsAny + Send + Sync {
451    /// Returns an identifier unique to the window.
452    fn id(&self) -> WindowId;
453
454    /// Returns the scale factor that can be used to map logical pixels to physical pixels, and
455    /// vice versa.
456    ///
457    /// Note that this value can change depending on user action (for example if the window is
458    /// moved to another screen); as such, tracking [`WindowEvent::ScaleFactorChanged`] events is
459    /// the most robust way to track the DPI you need to use to draw.
460    ///
461    /// This value may differ from [`MonitorHandle::scale_factor`].
462    ///
463    /// See the [`dpi`] crate for more information.
464    ///
465    /// ## Platform-specific
466    ///
467    /// The scale factor is calculated differently on different platforms:
468    ///
469    /// - **Windows:** On Windows 8 and 10, per-monitor scaling is readily configured by users from
470    ///   the display settings. While users are free to select any option they want, they're only
471    ///   given a selection of "nice" scale factors, i.e. 1.0, 1.25, 1.5... on Windows 7. The scale
472    ///   factor is global and changing it requires logging out. See [this article][windows_1] for
473    ///   technical details.
474    /// - **macOS:** Recent macOS versions allow the user to change the scaling factor for specific
475    ///   displays. When available, the user may pick a per-monitor scaling factor from a set of
476    ///   pre-defined settings. All "retina displays" have a scaling factor above 1.0 by default,
477    ///   but the specific value varies across devices.
478    /// - **X11:** Many man-hours have been spent trying to figure out how to handle DPI in X11.
479    ///   Winit currently uses a three-pronged approach:
480    ///   + Use the value in the `WINIT_X11_SCALE_FACTOR` environment variable if present.
481    ///   + If not present, use the value set in `Xft.dpi` in Xresources.
482    ///   + Otherwise, calculate the scale factor based on the millimeter monitor dimensions
483    ///     provided by XRandR.
484    ///
485    ///   If `WINIT_X11_SCALE_FACTOR` is set to `randr`, it'll ignore the `Xft.dpi` field and use
486    ///   the   XRandR scaling method. Generally speaking, you should try to configure the
487    ///   standard system   variables to do what you want before resorting to
488    ///   `WINIT_X11_SCALE_FACTOR`.
489    /// - **Wayland:** The scale factor is suggested by the compositor for each window individually
490    ///   by using the wp-fractional-scale protocol if available. Falls back to integer-scale
491    ///   factors otherwise.
492    ///
493    ///   The monitor scale factor may differ from the window scale factor.
494    /// - **iOS:** Scale factors are set by Apple to the value that best suits the device, and range
495    ///   from `1.0` to `3.0`. See [this article][apple_1] and [this article][apple_2] for more
496    ///   information.
497    ///
498    ///   This uses the underlying `UIView`'s [`contentScaleFactor`].
499    /// - **Android:** Scale factors are set by the manufacturer to the value that best suits the
500    ///   device, and range from `1.0` to `4.0`. See [this article][android_1] for more information.
501    ///
502    ///   This is currently unimplemented, and this function always returns 1.0.
503    /// - **Web:** The scale factor is the ratio between CSS pixels and the physical device pixels.
504    ///   In other words, it is the value of [`window.devicePixelRatio`][web_1]. It is affected by
505    ///   both the screen scaling and the browser zoom level and can go below `1.0`.
506    /// - **Orbital:** This is currently unimplemented, and this function always returns 1.0.
507    ///
508    /// [`WindowEvent::ScaleFactorChanged`]: crate::event::WindowEvent::ScaleFactorChanged
509    /// [windows_1]: https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
510    /// [apple_1]: https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html
511    /// [apple_2]: https://developer.apple.com/design/human-interface-guidelines/macos/icons-and-images/image-size-and-resolution/
512    /// [android_1]: https://developer.android.com/training/multiscreen/screendensities
513    /// [web_1]: https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio
514    /// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
515    fn scale_factor(&self) -> f64;
516
517    /// Queues a [`WindowEvent::RedrawRequested`] event to be emitted that aligns with the windowing
518    /// system drawing loop.
519    ///
520    /// This is the **strongly encouraged** method of redrawing windows, as it can integrate with
521    /// OS-requested redraws (e.g. when a window gets resized). To improve the event delivery
522    /// consider using [`Window::pre_present_notify`] as described in docs.
523    ///
524    /// Applications should always aim to redraw whenever they receive a `RedrawRequested` event.
525    ///
526    /// There are no strong guarantees about when exactly a `RedrawRequest` event will be emitted
527    /// with respect to other events, since the requirements can vary significantly between
528    /// windowing systems.
529    ///
530    /// However as the event aligns with the windowing system drawing loop, it may not arrive in
531    /// same or even next event loop iteration.
532    ///
533    /// ## Platform-specific
534    ///
535    /// - **Windows** This API uses `RedrawWindow` to request a `WM_PAINT` message and
536    ///   `RedrawRequested` is emitted in sync with any `WM_PAINT` messages.
537    /// - **Wayland:** The events are aligned with the frame callbacks when
538    ///   [`Window::pre_present_notify`] is used.
539    /// - **Web:** [`WindowEvent::RedrawRequested`] will be aligned with the
540    ///   `requestAnimationFrame`.
541    ///
542    /// [`WindowEvent::RedrawRequested`]: crate::event::WindowEvent::RedrawRequested
543    fn request_redraw(&self);
544
545    /// Notify the windowing system before presenting to the window.
546    ///
547    /// You should call this event after your drawing operations, but before you submit
548    /// the buffer to the display or commit your drawings. Doing so will help winit to properly
549    /// schedule and make assumptions about its internal state. For example, it could properly
550    /// throttle [`WindowEvent::RedrawRequested`].
551    ///
552    /// ## Example
553    ///
554    /// This example illustrates how it looks with OpenGL, but it applies to other graphics
555    /// APIs and software rendering.
556    ///
557    /// ```no_run
558    /// # use winit::window::Window;
559    /// # fn swap_buffers() {}
560    /// # fn scope(window: &dyn Window) {
561    /// // Do the actual drawing with OpenGL.
562    ///
563    /// // Notify winit that we're about to submit buffer to the windowing system.
564    /// window.pre_present_notify();
565    ///
566    /// // Submit buffer to the windowing system.
567    /// swap_buffers();
568    /// # }
569    /// ```
570    ///
571    /// ## Platform-specific
572    ///
573    /// - **Android / iOS / X11 / Web / Windows / macOS / Orbital:** Unsupported.
574    /// - **Wayland:** Schedules a frame callback to throttle [`WindowEvent::RedrawRequested`].
575    ///
576    /// [`WindowEvent::RedrawRequested`]: crate::event::WindowEvent::RedrawRequested
577    fn pre_present_notify(&self);
578
579    /// Reset the dead key state of the keyboard.
580    ///
581    /// This is useful when a dead key is bound to trigger an action. Then
582    /// this function can be called to reset the dead key state so that
583    /// follow-up text input won't be affected by the dead key.
584    ///
585    /// ## Platform-specific
586    /// - **Web, macOS:** Does nothing
587    // ---------------------------
588    // Developers' Note: If this cannot be implemented on every desktop platform
589    // at least, then this function should be provided through a platform specific
590    // extension trait
591    fn reset_dead_keys(&self);
592
593    /// Returns the position of the top-left hand corner of the window's client area relative to the
594    /// top-left hand corner of the desktop.
595    ///
596    /// The same conditions that apply to [`Window::outer_position`] apply to this method.
597    ///
598    /// ## Platform-specific
599    ///
600    /// - **iOS:** Returns the top left coordinates of the window's [safe area] in the screen space
601    ///   coordinate system.
602    /// - **Web:** Returns the top-left coordinates relative to the viewport. _Note: this returns
603    ///   the same value as [`Window::outer_position`]._
604    /// - **Android / Wayland:** Always returns [`RequestError::NotSupported`].
605    ///
606    /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
607    fn inner_position(&self) -> Result<PhysicalPosition<i32>, RequestError>;
608
609    /// Returns the position of the top-left hand corner of the window relative to the
610    /// top-left hand corner of the desktop.
611    ///
612    /// Note that the top-left hand corner of the desktop is not necessarily the same as
613    /// the screen. If the user uses a desktop with multiple monitors, the top-left hand corner
614    /// of the desktop is the top-left hand corner of the monitor at the top-left of the desktop.
615    ///
616    /// The coordinates can be negative if the top-left hand corner of the window is outside
617    /// of the visible screen region.
618    ///
619    /// ## Platform-specific
620    ///
621    /// - **iOS:** Returns the top left coordinates of the window in the screen space coordinate
622    ///   system.
623    /// - **Web:** Returns the top-left coordinates relative to the viewport.
624    /// - **Android / Wayland:** Always returns [`RequestError::NotSupported`].
625    fn outer_position(&self) -> Result<PhysicalPosition<i32>, RequestError>;
626
627    /// Modifies the position of the window.
628    ///
629    /// See [`Window::outer_position`] for more information about the coordinates.
630    /// This automatically un-maximizes the window if it's maximized.
631    ///
632    /// ```no_run
633    /// # use winit::dpi::{LogicalPosition, PhysicalPosition};
634    /// # use winit::window::Window;
635    /// # fn scope(window: &dyn Window) {
636    /// // Specify the position in logical dimensions like this:
637    /// window.set_outer_position(LogicalPosition::new(400.0, 200.0).into());
638    ///
639    /// // Or specify the position in physical dimensions like this:
640    /// window.set_outer_position(PhysicalPosition::new(400, 200).into());
641    /// # }
642    /// ```
643    ///
644    /// ## Platform-specific
645    ///
646    /// - **iOS:** Sets the top left coordinates of the window in the screen space coordinate
647    ///   system.
648    /// - **Web:** Sets the top-left coordinates relative to the viewport. Doesn't account for CSS
649    ///   [`transform`].
650    /// - **Android / Wayland:** Unsupported.
651    ///
652    /// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
653    fn set_outer_position(&self, position: Position);
654
655    /// Returns the size of the window's render-able surface.
656    ///
657    /// This is the dimensions you should pass to things like Wgpu or Glutin when configuring.
658    ///
659    /// ## Platform-specific
660    ///
661    /// - **iOS:** Returns the `PhysicalSize` of the window's [safe area] in screen space
662    ///   coordinates.
663    /// - **Web:** Returns the size of the canvas element. Doesn't account for CSS [`transform`].
664    ///
665    /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
666    /// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
667    fn surface_size(&self) -> PhysicalSize<u32>;
668
669    /// Request the new size for the surface.
670    ///
671    /// On platforms where the size is entirely controlled by the user the
672    /// applied size will be returned immediately, resize event in such case
673    /// may not be generated.
674    ///
675    /// On platforms where resizing is disallowed by the windowing system, the current surface size
676    /// is returned immediately, and the user one is ignored.
677    ///
678    /// When `None` is returned, it means that the request went to the display system,
679    /// and the actual size will be delivered later with the [`WindowEvent::SurfaceResized`].
680    ///
681    /// See [`Window::surface_size`] for more information about the values.
682    ///
683    /// The request could automatically un-maximize the window if it's maximized.
684    ///
685    /// ```no_run
686    /// # use winit::dpi::{LogicalSize, PhysicalSize};
687    /// # use winit::window::Window;
688    /// # fn scope(window: &dyn Window) {
689    /// // Specify the size in logical dimensions like this:
690    /// let _ = window.request_surface_size(LogicalSize::new(400.0, 200.0).into());
691    ///
692    /// // Or specify the size in physical dimensions like this:
693    /// let _ = window.request_surface_size(PhysicalSize::new(400, 200).into());
694    /// # }
695    /// ```
696    ///
697    /// ## Platform-specific
698    ///
699    /// - **Web:** Sets the size of the canvas element. Doesn't account for CSS [`transform`].
700    ///
701    /// [`WindowEvent::SurfaceResized`]: crate::event::WindowEvent::SurfaceResized
702    /// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
703    #[must_use]
704    fn request_surface_size(&self, size: Size) -> Option<PhysicalSize<u32>>;
705
706    /// Returns the size of the entire window.
707    ///
708    /// These dimensions include window decorations like the title bar and borders. If you don't
709    /// want that (and you usually don't), use [`Window::surface_size`] instead.
710    ///
711    /// ## Platform-specific
712    ///
713    /// - **iOS:** Returns the [`PhysicalSize`] of the window in screen space coordinates.
714    /// - **Web:** Returns the size of the canvas element. _Note: this returns the same value as
715    ///   [`Window::surface_size`]._
716    fn outer_size(&self) -> PhysicalSize<u32>;
717
718    /// Sets a minimum dimensions of the window's surface.
719    ///
720    /// ```no_run
721    /// # use winit::dpi::{LogicalSize, PhysicalSize};
722    /// # use winit::window::Window;
723    /// # fn scope(window: &dyn Window) {
724    /// // Specify the size in logical dimensions like this:
725    /// window.set_min_surface_size(Some(LogicalSize::new(400.0, 200.0).into()));
726    ///
727    /// // Or specify the size in physical dimensions like this:
728    /// window.set_min_surface_size(Some(PhysicalSize::new(400, 200).into()));
729    /// # }
730    /// ```
731    ///
732    /// ## Platform-specific
733    ///
734    /// - **iOS / Android / Orbital:** Unsupported.
735    fn set_min_surface_size(&self, min_size: Option<Size>);
736
737    /// Sets a maximum dimensions of the window's surface.
738    ///
739    /// ```no_run
740    /// # use winit::dpi::{LogicalSize, PhysicalSize};
741    /// # use winit::window::Window;
742    /// # fn scope(window: &dyn Window) {
743    /// // Specify the size in logical dimensions like this:
744    /// window.set_max_surface_size(Some(LogicalSize::new(400.0, 200.0).into()));
745    ///
746    /// // Or specify the size in physical dimensions like this:
747    /// window.set_max_surface_size(Some(PhysicalSize::new(400, 200).into()));
748    /// # }
749    /// ```
750    ///
751    /// ## Platform-specific
752    ///
753    /// - **iOS / Android / Orbital:** Unsupported.
754    fn set_max_surface_size(&self, max_size: Option<Size>);
755
756    /// Returns surface resize increments if any were set.
757    ///
758    /// ## Platform-specific
759    ///
760    /// - **iOS / Android / Web / Wayland / Orbital:** Always returns [`None`].
761    fn surface_resize_increments(&self) -> Option<PhysicalSize<u32>>;
762
763    /// Sets resize increments of the surface.
764    ///
765    /// This is a niche constraint hint usually employed by terminal emulators and other such apps
766    /// that need "blocky" resizes.
767    ///
768    /// ## Platform-specific
769    ///
770    /// - **macOS:** Increments are converted to logical size and then macOS rounds them to whole
771    ///   numbers.
772    /// - **Wayland:** Not implemented.
773    /// - **iOS / Android / Web / Orbital:** Unsupported.
774    fn set_surface_resize_increments(&self, increments: Option<Size>);
775
776    /// Modifies the title of the window.
777    ///
778    /// ## Platform-specific
779    ///
780    /// - **iOS / Android:** Unsupported.
781    fn set_title(&self, title: &str);
782
783    /// Change the window transparency state.
784    ///
785    /// This is just a hint that may not change anything about
786    /// the window transparency, however doing a mismatch between
787    /// the content of your window and this hint may result in
788    /// visual artifacts.
789    ///
790    /// The default value follows the [`WindowAttributes::with_transparent`].
791    ///
792    /// ## Platform-specific
793    ///
794    /// - **macOS:** This will reset the window's background color.
795    /// - **Web / iOS / Android:** Unsupported.
796    /// - **X11:** Can only be set while building the window, with
797    ///   [`WindowAttributes::with_transparent`].
798    fn set_transparent(&self, transparent: bool);
799
800    /// Change the window blur state.
801    ///
802    /// If `true`, this will make the transparent window background blurry.
803    ///
804    /// ## Platform-specific
805    ///
806    /// - **Android / iOS / X11 / Web / Windows:** Unsupported.
807    /// - **Wayland:** Only works with org_kde_kwin_blur_manager protocol.
808    fn set_blur(&self, blur: bool);
809
810    /// Modifies the window's visibility.
811    ///
812    /// If `false`, this will hide the window. If `true`, this will show the window.
813    ///
814    /// ## Platform-specific
815    ///
816    /// - **Android / Wayland / Web:** Unsupported.
817    fn set_visible(&self, visible: bool);
818
819    /// Gets the window's current visibility state.
820    ///
821    /// `None` means it couldn't be determined, so it is not recommended to use this to drive your
822    /// rendering backend.
823    ///
824    /// ## Platform-specific
825    ///
826    /// - **X11:** Not implemented.
827    /// - **Wayland / iOS / Android / Web:** Unsupported.
828    fn is_visible(&self) -> Option<bool>;
829
830    /// Sets whether the window is resizable or not.
831    ///
832    /// Note that making the window unresizable doesn't exempt you from handling
833    /// [`WindowEvent::SurfaceResized`], as that event can still be triggered by DPI scaling,
834    /// entering fullscreen mode, etc. Also, the window could still be resized by calling
835    /// [`Window::request_surface_size`].
836    ///
837    /// ## Platform-specific
838    ///
839    /// This only has an effect on desktop platforms.
840    ///
841    /// - **X11:** Due to a bug in XFCE, this has no effect on Xfwm.
842    /// - **iOS / Android / Web:** Unsupported.
843    ///
844    /// [`WindowEvent::SurfaceResized`]: crate::event::WindowEvent::SurfaceResized
845    fn set_resizable(&self, resizable: bool);
846
847    /// Gets the window's current resizable state.
848    ///
849    /// ## Platform-specific
850    ///
851    /// - **X11:** Not implemented.
852    /// - **iOS / Android / Web:** Unsupported.
853    fn is_resizable(&self) -> bool;
854
855    /// Sets the enabled window buttons.
856    ///
857    /// ## Platform-specific
858    ///
859    /// - **Wayland / X11 / Orbital:** Not implemented.
860    /// - **Web / iOS / Android:** Unsupported.
861    fn set_enabled_buttons(&self, buttons: WindowButtons);
862
863    /// Gets the enabled window buttons.
864    ///
865    /// ## Platform-specific
866    ///
867    /// - **Wayland / X11 / Orbital:** Not implemented. Always returns [`WindowButtons::all`].
868    /// - **Web / iOS / Android:** Unsupported. Always returns [`WindowButtons::all`].
869    fn enabled_buttons(&self) -> WindowButtons;
870
871    /// Sets the window to minimized or back
872    ///
873    /// ## Platform-specific
874    ///
875    /// - **iOS / Android / Web / Orbital:** Unsupported.
876    /// - **Wayland:** Un-minimize is unsupported.
877    fn set_minimized(&self, minimized: bool);
878
879    /// Gets the window's current minimized state.
880    ///
881    /// `None` will be returned, if the minimized state couldn't be determined.
882    ///
883    /// ## Note
884    ///
885    /// - You shouldn't stop rendering for minimized windows, however you could lower the fps.
886    ///
887    /// ## Platform-specific
888    ///
889    /// - **Wayland**: always `None`.
890    /// - **iOS / Android / Web / Orbital:** Unsupported.
891    fn is_minimized(&self) -> Option<bool>;
892
893    /// Sets the window to maximized or back.
894    ///
895    /// ## Platform-specific
896    ///
897    /// - **iOS / Android / Web:** Unsupported.
898    fn set_maximized(&self, maximized: bool);
899
900    /// Gets the window's current maximized state.
901    ///
902    /// ## Platform-specific
903    ///
904    /// - **iOS / Android / Web:** Unsupported.
905    fn is_maximized(&self) -> bool;
906
907    /// Sets the window to fullscreen or back.
908    ///
909    /// ## Platform-specific
910    ///
911    /// - **macOS:** [`Fullscreen::Exclusive`] provides true exclusive mode with a video mode
912    ///   change. *Caveat!* macOS doesn't provide task switching (or spaces!) while in exclusive
913    ///   fullscreen mode. This mode should be used when a video mode change is desired, but for a
914    ///   better user experience, borderless fullscreen might be preferred.
915    ///
916    ///   [`Fullscreen::Borderless`] provides a borderless fullscreen window on a
917    ///   separate space. This is the idiomatic way for fullscreen games to work
918    ///   on macOS. See `WindowExtMacOs::set_simple_fullscreen` if
919    ///   separate spaces are not preferred.
920    ///
921    ///   The dock and the menu bar are disabled in exclusive fullscreen mode.
922    /// - **Wayland:** Does not support exclusive fullscreen mode and will no-op a request.
923    /// - **Windows:** Screen saver is disabled in fullscreen mode.
924    /// - **Android / Orbital:** Unsupported.
925    /// - **Web:** Passing a [`MonitorHandle`] or [`VideoModeHandle`] that was not created with
926    #[cfg_attr(
927        any(web_platform, docsrs),
928        doc = "  [detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]"
929    )]
930    #[cfg_attr(not(any(web_platform, docsrs)), doc = "  detailed monitor permissions")]
931    ///   or calling without a [transient activation] does nothing.
932    ///
933    /// [transient activation]: https://developer.mozilla.org/en-US/docs/Glossary/Transient_activation
934    fn set_fullscreen(&self, fullscreen: Option<Fullscreen>);
935
936    /// Gets the window's current fullscreen state.
937    ///
938    /// ## Platform-specific
939    ///
940    /// - **Android / Orbital:** Will always return `None`.
941    /// - **Wayland:** Can return `Borderless(None)` when there are no monitors.
942    /// - **Web:** Can only return `None` or `Borderless(None)`.
943    fn fullscreen(&self) -> Option<Fullscreen>;
944
945    /// Turn window decorations on or off.
946    ///
947    /// Enable/disable window decorations provided by the server or Winit.
948    /// By default this is enabled. Note that fullscreen windows and windows on
949    /// mobile and Web platforms naturally do not have decorations.
950    ///
951    /// ## Platform-specific
952    ///
953    /// - **iOS / Android / Web:** No effect.
954    fn set_decorations(&self, decorations: bool);
955
956    /// Gets the window's current decorations state.
957    ///
958    /// Returns `true` when windows are decorated (server-side or by Winit).
959    /// Also returns `true` when no decorations are required (mobile, Web).
960    ///
961    /// ## Platform-specific
962    ///
963    /// - **iOS / Android / Web:** Always returns `true`.
964    fn is_decorated(&self) -> bool;
965
966    /// Change the window level.
967    ///
968    /// This is just a hint to the OS, and the system could ignore it.
969    ///
970    /// See [`WindowLevel`] for details.
971    fn set_window_level(&self, level: WindowLevel);
972
973    /// Sets the window icon.
974    ///
975    /// On Windows and X11, this is typically the small icon in the top-left
976    /// corner of the titlebar.
977    ///
978    /// ## Platform-specific
979    ///
980    /// - **iOS / Android / Web / Wayland / macOS / Orbital:** Unsupported.
981    ///
982    /// - **Windows:** Sets `ICON_SMALL`. The base size for a window icon is 16x16, but it's
983    ///   recommended to account for screen scaling and pick a multiple of that, i.e. 32x32.
984    ///
985    /// - **X11:** Has no universal guidelines for icon sizes, so you're at the whims of the WM.
986    ///   That said, it's usually in the same ballpark as on Windows.
987    fn set_window_icon(&self, window_icon: Option<Icon>);
988
989    /// Set the IME cursor editing area, where the `position` is the top left corner of that area
990    /// and `size` is the size of this area starting from the position. An example of such area
991    /// could be a input field in the UI or line in the editor.
992    ///
993    /// The windowing system could place a candidate box close to that area, but try to not obscure
994    /// the specified area, so the user input to it stays visible.
995    ///
996    /// The candidate box is the window / popup / overlay that allows you to select the desired
997    /// characters. The look of this box may differ between input devices, even on the same
998    /// platform.
999    ///
1000    /// (Apple's official term is "candidate window", see their [chinese] and [japanese] guides).
1001    ///
1002    /// ## Example
1003    ///
1004    /// ```no_run
1005    /// # use winit::dpi::{LogicalPosition, PhysicalPosition, LogicalSize, PhysicalSize};
1006    /// # use winit::window::Window;
1007    /// # fn scope(window: &dyn Window) {
1008    /// // Specify the position in logical dimensions like this:
1009    /// window.set_ime_cursor_area(
1010    ///     LogicalPosition::new(400.0, 200.0).into(),
1011    ///     LogicalSize::new(100, 100).into(),
1012    /// );
1013    ///
1014    /// // Or specify the position in physical dimensions like this:
1015    /// window.set_ime_cursor_area(
1016    ///     PhysicalPosition::new(400, 200).into(),
1017    ///     PhysicalSize::new(100, 100).into(),
1018    /// );
1019    /// # }
1020    /// ```
1021    ///
1022    /// ## Platform-specific
1023    ///
1024    /// - **X11:** - area is not supported, only position.
1025    /// - **iOS / Android / Web / Orbital:** Unsupported.
1026    ///
1027    /// [chinese]: https://support.apple.com/guide/chinese-input-method/use-the-candidate-window-cim12992/104/mac/12.0
1028    /// [japanese]: https://support.apple.com/guide/japanese-input-method/use-the-candidate-window-jpim10262/6.3/mac/12.0
1029    fn set_ime_cursor_area(&self, position: Position, size: Size);
1030
1031    /// Sets whether the window should get IME events
1032    ///
1033    /// When IME is allowed, the window will receive [`Ime`] events, and during the
1034    /// preedit phase the window will NOT get [`KeyboardInput`] events. The window
1035    /// should allow IME while it is expecting text input.
1036    ///
1037    /// When IME is not allowed, the window won't receive [`Ime`] events, and will
1038    /// receive [`KeyboardInput`] events for every keypress instead. Not allowing
1039    /// IME is useful for games for example.
1040    ///
1041    /// IME is **not** allowed by default.
1042    ///
1043    /// ## Platform-specific
1044    ///
1045    /// - **macOS:** IME must be enabled to receive text-input where dead-key sequences are
1046    ///   combined.
1047    /// - **iOS:** This will show / hide the soft keyboard.
1048    /// - **Android / Web / Orbital:** Unsupported.
1049    /// - **X11**: Enabling IME will disable dead keys reporting during compose.
1050    ///
1051    /// [`Ime`]: crate::event::WindowEvent::Ime
1052    /// [`KeyboardInput`]: crate::event::WindowEvent::KeyboardInput
1053    fn set_ime_allowed(&self, allowed: bool);
1054
1055    /// Sets the IME purpose for the window using [`ImePurpose`].
1056    ///
1057    /// ## Platform-specific
1058    ///
1059    /// - **iOS / Android / Web / Windows / X11 / macOS / Orbital:** Unsupported.
1060    fn set_ime_purpose(&self, purpose: ImePurpose);
1061
1062    /// Brings the window to the front and sets input focus. Has no effect if the window is
1063    /// already in focus, minimized, or not visible.
1064    ///
1065    /// This method steals input focus from other applications. Do not use this method unless
1066    /// you are certain that's what the user wants. Focus stealing can cause an extremely disruptive
1067    /// user experience.
1068    ///
1069    /// ## Platform-specific
1070    ///
1071    /// - **iOS / Android / Wayland / Orbital:** Unsupported.
1072    fn focus_window(&self);
1073
1074    /// Gets whether the window has keyboard focus.
1075    ///
1076    /// This queries the same state information as [`WindowEvent::Focused`].
1077    ///
1078    /// [`WindowEvent::Focused`]: crate::event::WindowEvent::Focused
1079    fn has_focus(&self) -> bool;
1080
1081    /// Requests user attention to the window, this has no effect if the application
1082    /// is already focused. How requesting for user attention manifests is platform dependent,
1083    /// see [`UserAttentionType`] for details.
1084    ///
1085    /// Providing `None` will unset the request for user attention. Unsetting the request for
1086    /// user attention might not be done automatically by the WM when the window receives input.
1087    ///
1088    /// ## Platform-specific
1089    ///
1090    /// - **iOS / Android / Web / Orbital:** Unsupported.
1091    /// - **macOS:** `None` has no effect.
1092    /// - **X11:** Requests for user attention must be manually cleared.
1093    /// - **Wayland:** Requires `xdg_activation_v1` protocol, `None` has no effect.
1094    fn request_user_attention(&self, request_type: Option<UserAttentionType>);
1095
1096    /// Set or override the window theme.
1097    ///
1098    /// Specify `None` to reset the theme to the system default.
1099    ///
1100    /// ## Platform-specific
1101    ///
1102    /// - **Wayland:** Sets the theme for the client side decorations. Using `None` will use dbus to
1103    ///   get the system preference.
1104    /// - **X11:** Sets `_GTK_THEME_VARIANT` hint to `dark` or `light` and if `None` is used, it
1105    ///   will default to  [`Theme::Dark`].
1106    /// - **iOS / Android / Web / Orbital:** Unsupported.
1107    fn set_theme(&self, theme: Option<Theme>);
1108
1109    /// Returns the current window theme.
1110    ///
1111    /// Returns `None` if it cannot be determined on the current platform.
1112    ///
1113    /// ## Platform-specific
1114    ///
1115    /// - **iOS / Android / x11 / Orbital:** Unsupported.
1116    /// - **Wayland:** Only returns theme overrides.
1117    fn theme(&self) -> Option<Theme>;
1118
1119    /// Prevents the window contents from being captured by other apps.
1120    ///
1121    /// ## Platform-specific
1122    ///
1123    /// - **macOS**: if `false`, [`NSWindowSharingNone`] is used but doesn't completely prevent all
1124    ///   apps from reading the window content, for instance, QuickTime.
1125    /// - **iOS / Android / x11 / Wayland / Web / Orbital:** Unsupported.
1126    ///
1127    /// [`NSWindowSharingNone`]: https://developer.apple.com/documentation/appkit/nswindowsharingtype/nswindowsharingnone
1128    fn set_content_protected(&self, protected: bool);
1129
1130    /// Gets the current title of the window.
1131    ///
1132    /// ## Platform-specific
1133    ///
1134    /// - **iOS / Android / x11 / Wayland / Web:** Unsupported. Always returns an empty string.
1135    fn title(&self) -> String;
1136
1137    /// Modifies the cursor icon of the window.
1138    ///
1139    /// ## Platform-specific
1140    ///
1141    /// - **iOS / Android / Orbital:** Unsupported.
1142    /// - **Web:** Custom cursors have to be loaded and decoded first, until then the previous
1143    ///   cursor is shown.
1144    fn set_cursor(&self, cursor: Cursor);
1145
1146    /// Changes the position of the cursor in window coordinates.
1147    ///
1148    /// ```no_run
1149    /// # use winit::dpi::{LogicalPosition, PhysicalPosition};
1150    /// # use winit::window::Window;
1151    /// # fn scope(window: &dyn Window) {
1152    /// // Specify the position in logical dimensions like this:
1153    /// window.set_cursor_position(LogicalPosition::new(400.0, 200.0).into());
1154    ///
1155    /// // Or specify the position in physical dimensions like this:
1156    /// window.set_cursor_position(PhysicalPosition::new(400, 200).into());
1157    /// # }
1158    /// ```
1159    ///
1160    /// ## Platform-specific
1161    ///
1162    /// - **Wayland**: Cursor must be in [`CursorGrabMode::Locked`].
1163    /// - **iOS / Android / Web / Orbital:** Always returns an [`RequestError::NotSupported`].
1164    fn set_cursor_position(&self, position: Position) -> Result<(), RequestError>;
1165
1166    /// Set grabbing [mode][CursorGrabMode] on the cursor preventing it from leaving the window.
1167    ///
1168    /// # Example
1169    ///
1170    /// First try confining the cursor, and if that fails, try locking it instead.
1171    ///
1172    /// ```no_run
1173    /// # use winit::window::{CursorGrabMode, Window};
1174    /// # fn scope(window: &dyn Window) {
1175    /// window
1176    ///     .set_cursor_grab(CursorGrabMode::Confined)
1177    ///     .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked))
1178    ///     .unwrap();
1179    /// # }
1180    /// ```
1181    fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError>;
1182
1183    /// Modifies the cursor's visibility.
1184    ///
1185    /// If `false`, this will hide the cursor. If `true`, this will show the cursor.
1186    ///
1187    /// ## Platform-specific
1188    ///
1189    /// - **Windows:** The cursor is only hidden within the confines of the window.
1190    /// - **X11:** The cursor is only hidden within the confines of the window.
1191    /// - **Wayland:** The cursor is only hidden within the confines of the window.
1192    /// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor
1193    ///   is outside of the window.
1194    /// - **iOS / Android:** Unsupported.
1195    fn set_cursor_visible(&self, visible: bool);
1196
1197    /// Moves the window with the left mouse button until the button is released.
1198    ///
1199    /// There's no guarantee that this will work unless the left mouse button was pressed
1200    /// immediately before this function is called.
1201    ///
1202    /// ## Platform-specific
1203    ///
1204    /// - **X11:** Un-grabs the cursor.
1205    /// - **Wayland:** Requires the cursor to be inside the window to be dragged.
1206    /// - **macOS:** May prevent the button release event to be triggered.
1207    /// - **iOS / Android / Web:** Always returns an [`RequestError::NotSupported`].
1208    fn drag_window(&self) -> Result<(), RequestError>;
1209
1210    /// Resizes the window with the left mouse button until the button is released.
1211    ///
1212    /// There's no guarantee that this will work unless the left mouse button was pressed
1213    /// immediately before this function is called.
1214    ///
1215    /// ## Platform-specific
1216    ///
1217    /// - **macOS:** Always returns an [`RequestError::NotSupported`]
1218    /// - **iOS / Android / Web:** Always returns an [`RequestError::NotSupported`].
1219    fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), RequestError>;
1220
1221    /// Show [window menu] at a specified position .
1222    ///
1223    /// This is the context menu that is normally shown when interacting with
1224    /// the title bar. This is useful when implementing custom decorations.
1225    ///
1226    /// ## Platform-specific
1227    /// **Android / iOS / macOS / Orbital / Wayland / Web / X11:** Unsupported.
1228    ///
1229    /// [window menu]: https://en.wikipedia.org/wiki/Common_menus_in_Microsoft_Windows#System_menu
1230    fn show_window_menu(&self, position: Position);
1231
1232    /// Modifies whether the window catches cursor events.
1233    ///
1234    /// If `true`, the window will catch the cursor events. If `false`, events are passed through
1235    /// the window such that any other window behind it receives them. By default hittest is
1236    /// enabled.
1237    ///
1238    /// ## Platform-specific
1239    ///
1240    /// - **iOS / Android / Web / Orbital:** Always returns an [`RequestError::NotSupported`].
1241    fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError>;
1242
1243    /// Returns the monitor on which the window currently resides.
1244    ///
1245    /// Returns `None` if current monitor can't be detected.
1246    fn current_monitor(&self) -> Option<MonitorHandle>;
1247
1248    /// Returns the list of all the monitors available on the system.
1249    ///
1250    /// This is the same as [`ActiveEventLoop::available_monitors`], and is provided for
1251    /// convenience.
1252    ///
1253    ///
1254    /// ## Platform-specific
1255    ///
1256    /// **Web:** Only returns the current monitor without
1257    #[cfg_attr(
1258        any(web_platform, docsrs),
1259        doc = "[detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]."
1260    )]
1261    #[cfg_attr(not(any(web_platform, docsrs)), doc = "detailed monitor permissions.")]
1262    ///
1263    #[rustfmt::skip]
1264    /// [`ActiveEventLoop::available_monitors`]: crate::event_loop::ActiveEventLoop::available_monitors
1265    fn available_monitors(&self) -> Box<dyn Iterator<Item = MonitorHandle>>;
1266
1267    /// Returns the primary monitor of the system.
1268    ///
1269    /// Returns `None` if it can't identify any monitor as a primary one.
1270    ///
1271    /// This is the same as [`ActiveEventLoop::primary_monitor`], and is provided for convenience.
1272    ///
1273    /// ## Platform-specific
1274    ///
1275    /// - **Wayland:** Always returns `None`.
1276    /// - **Web:** Always returns `None` without
1277    #[cfg_attr(
1278        any(web_platform, docsrs),
1279        doc = "  [detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]."
1280    )]
1281    #[cfg_attr(not(any(web_platform, docsrs)), doc = "  detailed monitor permissions.")]
1282    ///
1283    #[rustfmt::skip]
1284    /// [`ActiveEventLoop::primary_monitor`]: crate::event_loop::ActiveEventLoop::primary_monitor
1285    fn primary_monitor(&self) -> Option<MonitorHandle>;
1286
1287    /// Get the raw-window-handle v0.6 display handle.
1288    #[cfg(feature = "rwh_06")]
1289    fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle;
1290
1291    /// Get the raw-window-handle v0.6 window handle.
1292    #[cfg(feature = "rwh_06")]
1293    fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle;
1294}
1295
1296impl dyn Window {
1297    /// Create a new [`WindowAttributes`] which allows modifying the window's attributes before
1298    /// creation.
1299    pub fn default_attributes() -> WindowAttributes {
1300        WindowAttributes::default()
1301    }
1302}
1303
1304impl PartialEq for dyn Window + '_ {
1305    fn eq(&self, other: &dyn Window) -> bool {
1306        self.id().eq(&other.id())
1307    }
1308}
1309
1310impl Eq for dyn Window + '_ {}
1311
1312impl std::hash::Hash for dyn Window + '_ {
1313    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1314        self.id().hash(state);
1315    }
1316}
1317
1318#[cfg(feature = "rwh_06")]
1319impl rwh_06::HasDisplayHandle for dyn Window + '_ {
1320    fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
1321        self.rwh_06_display_handle().display_handle()
1322    }
1323}
1324
1325#[cfg(feature = "rwh_06")]
1326impl rwh_06::HasWindowHandle for dyn Window + '_ {
1327    fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
1328        self.rwh_06_window_handle().window_handle()
1329    }
1330}
1331
1332/// The behavior of cursor grabbing.
1333///
1334/// Use this enum with [`Window::set_cursor_grab`] to grab the cursor.
1335#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1336#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1337pub enum CursorGrabMode {
1338    /// No grabbing of the cursor is performed.
1339    None,
1340
1341    /// The cursor is confined to the window area.
1342    ///
1343    /// There's no guarantee that the cursor will be hidden. You should hide it by yourself if you
1344    /// want to do so.
1345    ///
1346    /// ## Platform-specific
1347    ///
1348    /// - **macOS:** Not implemented. Always returns [`RequestError::NotSupported`] for now.
1349    /// - **iOS / Android / Web:** Always returns an [`RequestError::NotSupported`].
1350    Confined,
1351
1352    /// The cursor is locked inside the window area to the certain position.
1353    ///
1354    /// There's no guarantee that the cursor will be hidden. You should hide it by yourself if you
1355    /// want to do so.
1356    ///
1357    /// ## Platform-specific
1358    ///
1359    /// - **X11 / Windows:** Not implemented. Always returns [`RequestError::NotSupported`] for
1360    ///   now.
1361    /// - **iOS / Android:** Always returns an [`RequestError::NotSupported`].
1362    Locked,
1363}
1364
1365/// Defines the orientation that a window resize will be performed.
1366#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1367#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1368pub enum ResizeDirection {
1369    East,
1370    North,
1371    NorthEast,
1372    NorthWest,
1373    South,
1374    SouthEast,
1375    SouthWest,
1376    West,
1377}
1378
1379impl From<ResizeDirection> for CursorIcon {
1380    fn from(direction: ResizeDirection) -> Self {
1381        use ResizeDirection::*;
1382        match direction {
1383            East => CursorIcon::EResize,
1384            North => CursorIcon::NResize,
1385            NorthEast => CursorIcon::NeResize,
1386            NorthWest => CursorIcon::NwResize,
1387            South => CursorIcon::SResize,
1388            SouthEast => CursorIcon::SeResize,
1389            SouthWest => CursorIcon::SwResize,
1390            West => CursorIcon::WResize,
1391        }
1392    }
1393}
1394
1395/// Fullscreen modes.
1396#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1397pub enum Fullscreen {
1398    Exclusive(VideoModeHandle),
1399
1400    /// Providing `None` to `Borderless` will fullscreen on the current monitor.
1401    Borderless(Option<MonitorHandle>),
1402}
1403
1404/// The theme variant to use.
1405#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1406#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1407pub enum Theme {
1408    /// Use the light variant.
1409    Light,
1410
1411    /// Use the dark variant.
1412    Dark,
1413}
1414
1415/// ## Platform-specific
1416///
1417/// - **X11:** Sets the WM's `XUrgencyHint`. No distinction between [`Critical`] and
1418///   [`Informational`].
1419///
1420/// [`Critical`]: Self::Critical
1421/// [`Informational`]: Self::Informational
1422#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
1423#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1424pub enum UserAttentionType {
1425    /// ## Platform-specific
1426    ///
1427    /// - **macOS:** Bounces the dock icon until the application is in focus.
1428    /// - **Windows:** Flashes both the window and the taskbar button until the application is in
1429    ///   focus.
1430    Critical,
1431
1432    /// ## Platform-specific
1433    ///
1434    /// - **macOS:** Bounces the dock icon once.
1435    /// - **Windows:** Flashes the taskbar button until the application is in focus.
1436    #[default]
1437    Informational,
1438}
1439
1440bitflags::bitflags! {
1441    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1442    pub struct WindowButtons: u32 {
1443        const CLOSE  = 1 << 0;
1444        const MINIMIZE  = 1 << 1;
1445        const MAXIMIZE  = 1 << 2;
1446    }
1447}
1448
1449/// A window level groups windows with respect to their z-position.
1450///
1451/// The relative ordering between windows in different window levels is fixed.
1452/// The z-order of a window within the same window level may change dynamically on user interaction.
1453///
1454/// ## Platform-specific
1455///
1456/// - **iOS / Android / Web / Wayland:** Unsupported.
1457#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)]
1458#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1459pub enum WindowLevel {
1460    /// The window will always be below normal windows.
1461    ///
1462    /// This is useful for a widget-based app.
1463    AlwaysOnBottom,
1464
1465    /// The default.
1466    #[default]
1467    Normal,
1468
1469    /// The window will always be on top of normal windows.
1470    AlwaysOnTop,
1471}
1472
1473/// Generic IME purposes for use in [`Window::set_ime_purpose`].
1474///
1475/// The purpose may improve UX by optimizing the IME for the specific use case,
1476/// if winit can express the purpose to the platform and the platform reacts accordingly.
1477///
1478/// ## Platform-specific
1479///
1480/// - **iOS / Android / Web / Windows / X11 / macOS / Orbital:** Unsupported.
1481#[non_exhaustive]
1482#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
1483#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1484pub enum ImePurpose {
1485    /// No special hints for the IME (default).
1486    Normal,
1487    /// The IME is used for password input.
1488    Password,
1489    /// The IME is used to input into a terminal.
1490    ///
1491    /// For example, that could alter OSK on Wayland to show extra buttons.
1492    Terminal,
1493}
1494
1495impl Default for ImePurpose {
1496    fn default() -> Self {
1497        Self::Normal
1498    }
1499}
1500
1501/// An opaque token used to activate the [`Window`].
1502///
1503/// [`Window`]: crate::window::Window
1504#[derive(Debug, PartialEq, Eq, Clone, Hash)]
1505pub struct ActivationToken {
1506    pub(crate) _token: String,
1507}
1508
1509impl ActivationToken {
1510    pub(crate) fn _new(_token: String) -> Self {
1511        Self { _token }
1512    }
1513}