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}