winit/
window.rs

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