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