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 /// - **Orbital / Wayland:** Does not support exclusive fullscreen mode and will no-op a
923 /// request.
924 /// - **Windows:** Screen saver is disabled in fullscreen mode.
925 /// - **Android / Orbital:** Unsupported.
926 /// - **Web:** Passing a [`MonitorHandle`] or [`VideoModeHandle`] that was not created with
927 #[cfg_attr(
928 any(web_platform, docsrs),
929 doc = " [detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]"
930 )]
931 #[cfg_attr(not(any(web_platform, docsrs)), doc = " detailed monitor permissions")]
932 /// or calling without a [transient activation] does nothing.
933 ///
934 /// [transient activation]: https://developer.mozilla.org/en-US/docs/Glossary/Transient_activation
935 fn set_fullscreen(&self, fullscreen: Option<Fullscreen>);
936
937 /// Gets the window's current fullscreen state.
938 ///
939 /// ## Platform-specific
940 ///
941 /// - **Android:** Will always return `None`.
942 /// - **Orbital / Web:** Can only return `None` or `Borderless(None)`.
943 /// - **Wayland:** Can return `Borderless(None)` when there are no monitors.
944 fn fullscreen(&self) -> Option<Fullscreen>;
945
946 /// Turn window decorations on or off.
947 ///
948 /// Enable/disable window decorations provided by the server or Winit.
949 /// By default this is enabled. Note that fullscreen windows and windows on
950 /// mobile and Web platforms naturally do not have decorations.
951 ///
952 /// ## Platform-specific
953 ///
954 /// - **iOS / Android / Web:** No effect.
955 fn set_decorations(&self, decorations: bool);
956
957 /// Gets the window's current decorations state.
958 ///
959 /// Returns `true` when windows are decorated (server-side or by Winit).
960 /// Also returns `true` when no decorations are required (mobile, Web).
961 ///
962 /// ## Platform-specific
963 ///
964 /// - **iOS / Android / Web:** Always returns `true`.
965 fn is_decorated(&self) -> bool;
966
967 /// Change the window level.
968 ///
969 /// This is just a hint to the OS, and the system could ignore it.
970 ///
971 /// See [`WindowLevel`] for details.
972 fn set_window_level(&self, level: WindowLevel);
973
974 /// Sets the window icon.
975 ///
976 /// On Windows and X11, this is typically the small icon in the top-left
977 /// corner of the titlebar.
978 ///
979 /// ## Platform-specific
980 ///
981 /// - **iOS / Android / Web / Wayland / macOS / Orbital:** Unsupported.
982 ///
983 /// - **Windows:** Sets `ICON_SMALL`. The base size for a window icon is 16x16, but it's
984 /// recommended to account for screen scaling and pick a multiple of that, i.e. 32x32.
985 ///
986 /// - **X11:** Has no universal guidelines for icon sizes, so you're at the whims of the WM.
987 /// That said, it's usually in the same ballpark as on Windows.
988 fn set_window_icon(&self, window_icon: Option<Icon>);
989
990 /// Set the IME cursor editing area, where the `position` is the top left corner of that area
991 /// and `size` is the size of this area starting from the position. An example of such area
992 /// could be a input field in the UI or line in the editor.
993 ///
994 /// The windowing system could place a candidate box close to that area, but try to not obscure
995 /// the specified area, so the user input to it stays visible.
996 ///
997 /// The candidate box is the window / popup / overlay that allows you to select the desired
998 /// characters. The look of this box may differ between input devices, even on the same
999 /// platform.
1000 ///
1001 /// (Apple's official term is "candidate window", see their [chinese] and [japanese] guides).
1002 ///
1003 /// ## Example
1004 ///
1005 /// ```no_run
1006 /// # use winit::dpi::{LogicalPosition, PhysicalPosition, LogicalSize, PhysicalSize};
1007 /// # use winit::window::Window;
1008 /// # fn scope(window: &dyn Window) {
1009 /// // Specify the position in logical dimensions like this:
1010 /// window.set_ime_cursor_area(
1011 /// LogicalPosition::new(400.0, 200.0).into(),
1012 /// LogicalSize::new(100, 100).into(),
1013 /// );
1014 ///
1015 /// // Or specify the position in physical dimensions like this:
1016 /// window.set_ime_cursor_area(
1017 /// PhysicalPosition::new(400, 200).into(),
1018 /// PhysicalSize::new(100, 100).into(),
1019 /// );
1020 /// # }
1021 /// ```
1022 ///
1023 /// ## Platform-specific
1024 ///
1025 /// - **X11:** - area is not supported, only position.
1026 /// - **iOS / Android / Web / Orbital:** Unsupported.
1027 ///
1028 /// [chinese]: https://support.apple.com/guide/chinese-input-method/use-the-candidate-window-cim12992/104/mac/12.0
1029 /// [japanese]: https://support.apple.com/guide/japanese-input-method/use-the-candidate-window-jpim10262/6.3/mac/12.0
1030 fn set_ime_cursor_area(&self, position: Position, size: Size);
1031
1032 /// Sets whether the window should get IME events
1033 ///
1034 /// When IME is allowed, the window will receive [`Ime`] events, and during the
1035 /// preedit phase the window will NOT get [`KeyboardInput`] events. The window
1036 /// should allow IME while it is expecting text input.
1037 ///
1038 /// When IME is not allowed, the window won't receive [`Ime`] events, and will
1039 /// receive [`KeyboardInput`] events for every keypress instead. Not allowing
1040 /// IME is useful for games for example.
1041 ///
1042 /// IME is **not** allowed by default.
1043 ///
1044 /// ## Platform-specific
1045 ///
1046 /// - **macOS:** IME must be enabled to receive text-input where dead-key sequences are
1047 /// combined.
1048 /// - **iOS:** This will show / hide the soft keyboard.
1049 /// - **Android / Web / Orbital:** Unsupported.
1050 /// - **X11**: Enabling IME will disable dead keys reporting during compose.
1051 ///
1052 /// [`Ime`]: crate::event::WindowEvent::Ime
1053 /// [`KeyboardInput`]: crate::event::WindowEvent::KeyboardInput
1054 fn set_ime_allowed(&self, allowed: bool);
1055
1056 /// Sets the IME purpose for the window using [`ImePurpose`].
1057 ///
1058 /// ## Platform-specific
1059 ///
1060 /// - **iOS / Android / Web / Windows / X11 / macOS / Orbital:** Unsupported.
1061 fn set_ime_purpose(&self, purpose: ImePurpose);
1062
1063 /// Brings the window to the front and sets input focus. Has no effect if the window is
1064 /// already in focus, minimized, or not visible.
1065 ///
1066 /// This method steals input focus from other applications. Do not use this method unless
1067 /// you are certain that's what the user wants. Focus stealing can cause an extremely disruptive
1068 /// user experience.
1069 ///
1070 /// ## Platform-specific
1071 ///
1072 /// - **iOS / Android / Wayland / Orbital:** Unsupported.
1073 fn focus_window(&self);
1074
1075 /// Gets whether the window has keyboard focus.
1076 ///
1077 /// This queries the same state information as [`WindowEvent::Focused`].
1078 ///
1079 /// [`WindowEvent::Focused`]: crate::event::WindowEvent::Focused
1080 fn has_focus(&self) -> bool;
1081
1082 /// Requests user attention to the window, this has no effect if the application
1083 /// is already focused. How requesting for user attention manifests is platform dependent,
1084 /// see [`UserAttentionType`] for details.
1085 ///
1086 /// Providing `None` will unset the request for user attention. Unsetting the request for
1087 /// user attention might not be done automatically by the WM when the window receives input.
1088 ///
1089 /// ## Platform-specific
1090 ///
1091 /// - **iOS / Android / Web / Orbital:** Unsupported.
1092 /// - **macOS:** `None` has no effect.
1093 /// - **X11:** Requests for user attention must be manually cleared.
1094 /// - **Wayland:** Requires `xdg_activation_v1` protocol, `None` has no effect.
1095 fn request_user_attention(&self, request_type: Option<UserAttentionType>);
1096
1097 /// Set or override the window theme.
1098 ///
1099 /// Specify `None` to reset the theme to the system default.
1100 ///
1101 /// ## Platform-specific
1102 ///
1103 /// - **Wayland:** Sets the theme for the client side decorations. Using `None` will use dbus to
1104 /// get the system preference.
1105 /// - **X11:** Sets `_GTK_THEME_VARIANT` hint to `dark` or `light` and if `None` is used, it
1106 /// will default to [`Theme::Dark`].
1107 /// - **iOS / Android / Web / Orbital:** Unsupported.
1108 fn set_theme(&self, theme: Option<Theme>);
1109
1110 /// Returns the current window theme.
1111 ///
1112 /// Returns `None` if it cannot be determined on the current platform.
1113 ///
1114 /// ## Platform-specific
1115 ///
1116 /// - **iOS / Android / x11 / Orbital:** Unsupported.
1117 /// - **Wayland:** Only returns theme overrides.
1118 fn theme(&self) -> Option<Theme>;
1119
1120 /// Prevents the window contents from being captured by other apps.
1121 ///
1122 /// ## Platform-specific
1123 ///
1124 /// - **macOS**: if `false`, [`NSWindowSharingNone`] is used but doesn't completely prevent all
1125 /// apps from reading the window content, for instance, QuickTime.
1126 /// - **iOS / Android / x11 / Wayland / Web / Orbital:** Unsupported.
1127 ///
1128 /// [`NSWindowSharingNone`]: https://developer.apple.com/documentation/appkit/nswindowsharingtype/nswindowsharingnone
1129 fn set_content_protected(&self, protected: bool);
1130
1131 /// Gets the current title of the window.
1132 ///
1133 /// ## Platform-specific
1134 ///
1135 /// - **iOS / Android / x11 / Wayland / Web:** Unsupported. Always returns an empty string.
1136 fn title(&self) -> String;
1137
1138 /// Modifies the cursor icon of the window.
1139 ///
1140 /// ## Platform-specific
1141 ///
1142 /// - **iOS / Android / Orbital:** Unsupported.
1143 /// - **Web:** Custom cursors have to be loaded and decoded first, until then the previous
1144 /// cursor is shown.
1145 fn set_cursor(&self, cursor: Cursor);
1146
1147 /// Changes the position of the cursor in window coordinates.
1148 ///
1149 /// ```no_run
1150 /// # use winit::dpi::{LogicalPosition, PhysicalPosition};
1151 /// # use winit::window::Window;
1152 /// # fn scope(window: &dyn Window) {
1153 /// // Specify the position in logical dimensions like this:
1154 /// window.set_cursor_position(LogicalPosition::new(400.0, 200.0).into());
1155 ///
1156 /// // Or specify the position in physical dimensions like this:
1157 /// window.set_cursor_position(PhysicalPosition::new(400, 200).into());
1158 /// # }
1159 /// ```
1160 ///
1161 /// ## Platform-specific
1162 ///
1163 /// - **Wayland**: Cursor must be in [`CursorGrabMode::Locked`].
1164 /// - **iOS / Android / Web / Orbital:** Always returns an [`RequestError::NotSupported`].
1165 fn set_cursor_position(&self, position: Position) -> Result<(), RequestError>;
1166
1167 /// Set grabbing [mode][CursorGrabMode] on the cursor preventing it from leaving the window.
1168 ///
1169 /// # Example
1170 ///
1171 /// First try confining the cursor, and if that fails, try locking it instead.
1172 ///
1173 /// ```no_run
1174 /// # use winit::window::{CursorGrabMode, Window};
1175 /// # fn scope(window: &dyn Window) {
1176 /// window
1177 /// .set_cursor_grab(CursorGrabMode::Confined)
1178 /// .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked))
1179 /// .unwrap();
1180 /// # }
1181 /// ```
1182 fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError>;
1183
1184 /// Modifies the cursor's visibility.
1185 ///
1186 /// If `false`, this will hide the cursor. If `true`, this will show the cursor.
1187 ///
1188 /// ## Platform-specific
1189 ///
1190 /// - **Windows:** The cursor is only hidden within the confines of the window.
1191 /// - **X11:** The cursor is only hidden within the confines of the window.
1192 /// - **Wayland:** The cursor is only hidden within the confines of the window.
1193 /// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor
1194 /// is outside of the window.
1195 /// - **iOS / Android:** Unsupported.
1196 fn set_cursor_visible(&self, visible: bool);
1197
1198 /// Moves the window with the left mouse button until the button is released.
1199 ///
1200 /// There's no guarantee that this will work unless the left mouse button was pressed
1201 /// immediately before this function is called.
1202 ///
1203 /// ## Platform-specific
1204 ///
1205 /// - **X11:** Un-grabs the cursor.
1206 /// - **Wayland:** Requires the cursor to be inside the window to be dragged.
1207 /// - **macOS:** May prevent the button release event to be triggered.
1208 /// - **iOS / Android / Web:** Always returns an [`RequestError::NotSupported`].
1209 fn drag_window(&self) -> Result<(), RequestError>;
1210
1211 /// Resizes the window with the left mouse button until the button is released.
1212 ///
1213 /// There's no guarantee that this will work unless the left mouse button was pressed
1214 /// immediately before this function is called.
1215 ///
1216 /// ## Platform-specific
1217 ///
1218 /// - **macOS:** Always returns an [`RequestError::NotSupported`]
1219 /// - **iOS / Android / Web:** Always returns an [`RequestError::NotSupported`].
1220 fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), RequestError>;
1221
1222 /// Show [window menu] at a specified position .
1223 ///
1224 /// This is the context menu that is normally shown when interacting with
1225 /// the title bar. This is useful when implementing custom decorations.
1226 ///
1227 /// ## Platform-specific
1228 /// **Android / iOS / macOS / Orbital / Wayland / Web / X11:** Unsupported.
1229 ///
1230 /// [window menu]: https://en.wikipedia.org/wiki/Common_menus_in_Microsoft_Windows#System_menu
1231 fn show_window_menu(&self, position: Position);
1232
1233 /// Modifies whether the window catches cursor events.
1234 ///
1235 /// If `true`, the window will catch the cursor events. If `false`, events are passed through
1236 /// the window such that any other window behind it receives them. By default hittest is
1237 /// enabled.
1238 ///
1239 /// ## Platform-specific
1240 ///
1241 /// - **iOS / Android / Web / Orbital:** Always returns an [`RequestError::NotSupported`].
1242 fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError>;
1243
1244 /// Returns the monitor on which the window currently resides.
1245 ///
1246 /// Returns `None` if current monitor can't be detected.
1247 fn current_monitor(&self) -> Option<MonitorHandle>;
1248
1249 /// Returns the list of all the monitors available on the system.
1250 ///
1251 /// This is the same as [`ActiveEventLoop::available_monitors`], and is provided for
1252 /// convenience.
1253 ///
1254 ///
1255 /// ## Platform-specific
1256 ///
1257 /// **Web:** Only returns the current monitor without
1258 #[cfg_attr(
1259 any(web_platform, docsrs),
1260 doc = "[detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]."
1261 )]
1262 #[cfg_attr(not(any(web_platform, docsrs)), doc = "detailed monitor permissions.")]
1263 ///
1264 #[rustfmt::skip]
1265 /// [`ActiveEventLoop::available_monitors`]: crate::event_loop::ActiveEventLoop::available_monitors
1266 fn available_monitors(&self) -> Box<dyn Iterator<Item = MonitorHandle>>;
1267
1268 /// Returns the primary monitor of the system.
1269 ///
1270 /// Returns `None` if it can't identify any monitor as a primary one.
1271 ///
1272 /// This is the same as [`ActiveEventLoop::primary_monitor`], and is provided for convenience.
1273 ///
1274 /// ## Platform-specific
1275 ///
1276 /// - **Wayland:** Always returns `None`.
1277 /// - **Web:** Always returns `None` without
1278 #[cfg_attr(
1279 any(web_platform, docsrs),
1280 doc = " [detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]."
1281 )]
1282 #[cfg_attr(not(any(web_platform, docsrs)), doc = " detailed monitor permissions.")]
1283 ///
1284 #[rustfmt::skip]
1285 /// [`ActiveEventLoop::primary_monitor`]: crate::event_loop::ActiveEventLoop::primary_monitor
1286 fn primary_monitor(&self) -> Option<MonitorHandle>;
1287
1288 /// Get the raw-window-handle v0.6 display handle.
1289 #[cfg(feature = "rwh_06")]
1290 fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle;
1291
1292 /// Get the raw-window-handle v0.6 window handle.
1293 #[cfg(feature = "rwh_06")]
1294 fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle;
1295}
1296
1297impl dyn Window {
1298 /// Create a new [`WindowAttributes`] which allows modifying the window's attributes before
1299 /// creation.
1300 pub fn default_attributes() -> WindowAttributes {
1301 WindowAttributes::default()
1302 }
1303}
1304
1305impl PartialEq for dyn Window + '_ {
1306 fn eq(&self, other: &dyn Window) -> bool {
1307 self.id().eq(&other.id())
1308 }
1309}
1310
1311impl Eq for dyn Window + '_ {}
1312
1313impl std::hash::Hash for dyn Window + '_ {
1314 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1315 self.id().hash(state);
1316 }
1317}
1318
1319#[cfg(feature = "rwh_06")]
1320impl rwh_06::HasDisplayHandle for dyn Window + '_ {
1321 fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
1322 self.rwh_06_display_handle().display_handle()
1323 }
1324}
1325
1326#[cfg(feature = "rwh_06")]
1327impl rwh_06::HasWindowHandle for dyn Window + '_ {
1328 fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
1329 self.rwh_06_window_handle().window_handle()
1330 }
1331}
1332
1333/// The behavior of cursor grabbing.
1334///
1335/// Use this enum with [`Window::set_cursor_grab`] to grab the cursor.
1336#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1337#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1338pub enum CursorGrabMode {
1339 /// No grabbing of the cursor is performed.
1340 None,
1341
1342 /// The cursor is confined to the window area.
1343 ///
1344 /// There's no guarantee that the cursor will be hidden. You should hide it by yourself if you
1345 /// want to do so.
1346 ///
1347 /// ## Platform-specific
1348 ///
1349 /// - **macOS:** Not implemented. Always returns [`RequestError::NotSupported`] for now.
1350 /// - **iOS / Android / Web:** Always returns an [`RequestError::NotSupported`].
1351 Confined,
1352
1353 /// The cursor is locked inside the window area to the certain position.
1354 ///
1355 /// There's no guarantee that the cursor will be hidden. You should hide it by yourself if you
1356 /// want to do so.
1357 ///
1358 /// ## Platform-specific
1359 ///
1360 /// - **X11 / Windows:** Not implemented. Always returns [`RequestError::NotSupported`] for
1361 /// now.
1362 /// - **iOS / Android:** Always returns an [`RequestError::NotSupported`].
1363 Locked,
1364}
1365
1366/// Defines the orientation that a window resize will be performed.
1367#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1368#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1369pub enum ResizeDirection {
1370 East,
1371 North,
1372 NorthEast,
1373 NorthWest,
1374 South,
1375 SouthEast,
1376 SouthWest,
1377 West,
1378}
1379
1380impl From<ResizeDirection> for CursorIcon {
1381 fn from(direction: ResizeDirection) -> Self {
1382 use ResizeDirection::*;
1383 match direction {
1384 East => CursorIcon::EResize,
1385 North => CursorIcon::NResize,
1386 NorthEast => CursorIcon::NeResize,
1387 NorthWest => CursorIcon::NwResize,
1388 South => CursorIcon::SResize,
1389 SouthEast => CursorIcon::SeResize,
1390 SouthWest => CursorIcon::SwResize,
1391 West => CursorIcon::WResize,
1392 }
1393 }
1394}
1395
1396/// Fullscreen modes.
1397#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1398pub enum Fullscreen {
1399 Exclusive(VideoModeHandle),
1400
1401 /// Providing `None` to `Borderless` will fullscreen on the current monitor.
1402 Borderless(Option<MonitorHandle>),
1403}
1404
1405/// The theme variant to use.
1406#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1407#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1408pub enum Theme {
1409 /// Use the light variant.
1410 Light,
1411
1412 /// Use the dark variant.
1413 Dark,
1414}
1415
1416/// ## Platform-specific
1417///
1418/// - **X11:** Sets the WM's `XUrgencyHint`. No distinction between [`Critical`] and
1419/// [`Informational`].
1420///
1421/// [`Critical`]: Self::Critical
1422/// [`Informational`]: Self::Informational
1423#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
1424#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1425pub enum UserAttentionType {
1426 /// ## Platform-specific
1427 ///
1428 /// - **macOS:** Bounces the dock icon until the application is in focus.
1429 /// - **Windows:** Flashes both the window and the taskbar button until the application is in
1430 /// focus.
1431 Critical,
1432
1433 /// ## Platform-specific
1434 ///
1435 /// - **macOS:** Bounces the dock icon once.
1436 /// - **Windows:** Flashes the taskbar button until the application is in focus.
1437 #[default]
1438 Informational,
1439}
1440
1441bitflags::bitflags! {
1442 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1443 pub struct WindowButtons: u32 {
1444 const CLOSE = 1 << 0;
1445 const MINIMIZE = 1 << 1;
1446 const MAXIMIZE = 1 << 2;
1447 }
1448}
1449
1450/// A window level groups windows with respect to their z-position.
1451///
1452/// The relative ordering between windows in different window levels is fixed.
1453/// The z-order of a window within the same window level may change dynamically on user interaction.
1454///
1455/// ## Platform-specific
1456///
1457/// - **iOS / Android / Web / Wayland:** Unsupported.
1458#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)]
1459#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1460pub enum WindowLevel {
1461 /// The window will always be below normal windows.
1462 ///
1463 /// This is useful for a widget-based app.
1464 AlwaysOnBottom,
1465
1466 /// The default.
1467 #[default]
1468 Normal,
1469
1470 /// The window will always be on top of normal windows.
1471 AlwaysOnTop,
1472}
1473
1474/// Generic IME purposes for use in [`Window::set_ime_purpose`].
1475///
1476/// The purpose may improve UX by optimizing the IME for the specific use case,
1477/// if winit can express the purpose to the platform and the platform reacts accordingly.
1478///
1479/// ## Platform-specific
1480///
1481/// - **iOS / Android / Web / Windows / X11 / macOS / Orbital:** Unsupported.
1482#[non_exhaustive]
1483#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
1484#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1485pub enum ImePurpose {
1486 /// No special hints for the IME (default).
1487 Normal,
1488 /// The IME is used for password input.
1489 Password,
1490 /// The IME is used to input into a terminal.
1491 ///
1492 /// For example, that could alter OSK on Wayland to show extra buttons.
1493 Terminal,
1494}
1495
1496impl Default for ImePurpose {
1497 fn default() -> Self {
1498 Self::Normal
1499 }
1500}
1501
1502/// An opaque token used to activate the [`Window`].
1503///
1504/// [`Window`]: crate::window::Window
1505#[derive(Debug, PartialEq, Eq, Clone, Hash)]
1506pub struct ActivationToken {
1507 pub(crate) _token: String,
1508}
1509
1510impl ActivationToken {
1511 pub(crate) fn _new(_token: String) -> Self {
1512 Self { _token }
1513 }
1514}