cart_tmp_winit/window.rs
1//! The `Window` struct and associated types.
2use std::fmt;
3
4use crate::{
5 dpi::{PhysicalPosition, PhysicalSize, Position, Size},
6 error::{ExternalError, NotSupportedError, OsError},
7 event_loop::EventLoopWindowTarget,
8 monitor::{MonitorHandle, VideoMode},
9 platform_impl,
10};
11
12pub use crate::icon::{BadIcon, Icon};
13
14/// Represents a window.
15///
16/// # Example
17///
18/// ```no_run
19/// use winit::{
20/// event::{Event, WindowEvent},
21/// event_loop::{ControlFlow, EventLoop},
22/// window::Window,
23/// };
24///
25/// let mut event_loop = EventLoop::new();
26/// let window = Window::new(&event_loop).unwrap();
27///
28/// event_loop.run(move |event, _, control_flow| {
29/// *control_flow = ControlFlow::Wait;
30///
31/// match event {
32/// Event::WindowEvent {
33/// event: WindowEvent::CloseRequested,
34/// ..
35/// } => *control_flow = ControlFlow::Exit,
36/// _ => (),
37/// }
38/// });
39/// ```
40pub struct Window {
41 pub(crate) window: platform_impl::Window,
42}
43
44impl fmt::Debug for Window {
45 fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result {
46 fmtr.pad("Window { .. }")
47 }
48}
49
50impl Drop for Window {
51 fn drop(&mut self) {
52 // If the window is in exclusive fullscreen, we must restore the desktop
53 // video mode (generally this would be done on application exit, but
54 // closing the window doesn't necessarily always mean application exit,
55 // such as when there are multiple windows)
56 if let Some(Fullscreen::Exclusive(_)) = self.fullscreen() {
57 self.set_fullscreen(None);
58 }
59 }
60}
61
62/// Identifier of a window. Unique for each window.
63///
64/// Can be obtained with `window.id()`.
65///
66/// Whenever you receive an event specific to a window, this event contains a `WindowId` which you
67/// can then compare to the ids of your windows.
68#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
69pub struct WindowId(pub(crate) platform_impl::WindowId);
70
71impl WindowId {
72 /// Returns a dummy `WindowId`, useful for unit testing. The only guarantee made about the return
73 /// value of this function is that it will always be equal to itself and to future values returned
74 /// by this function. No other guarantees are made. This may be equal to a real `WindowId`.
75 ///
76 /// **Passing this into a winit function will result in undefined behavior.**
77 pub unsafe fn dummy() -> Self {
78 WindowId(platform_impl::WindowId::dummy())
79 }
80}
81
82/// Object that allows you to build windows.
83#[derive(Clone, Default)]
84pub struct WindowBuilder {
85 /// The attributes to use to create the window.
86 pub window: WindowAttributes,
87
88 // Platform-specific configuration.
89 pub(crate) platform_specific: platform_impl::PlatformSpecificWindowBuilderAttributes,
90}
91
92impl fmt::Debug for WindowBuilder {
93 fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result {
94 fmtr.debug_struct("WindowBuilder")
95 .field("window", &self.window)
96 .finish()
97 }
98}
99
100/// Attributes to use when creating a window.
101#[derive(Debug, Clone)]
102pub struct WindowAttributes {
103 /// The dimensions of the window. If this is `None`, some platform-specific dimensions will be
104 /// used.
105 ///
106 /// The default is `None`.
107 pub inner_size: Option<Size>,
108
109 /// The minimum dimensions a window can be, If this is `None`, the window will have no minimum dimensions (aside from reserved).
110 ///
111 /// The default is `None`.
112 pub min_inner_size: Option<Size>,
113
114 /// The maximum dimensions a window can be, If this is `None`, the maximum will have no maximum or will be set to the primary monitor's dimensions by the platform.
115 ///
116 /// The default is `None`.
117 pub max_inner_size: Option<Size>,
118
119 /// Whether the window is resizable or not.
120 ///
121 /// The default is `true`.
122 pub resizable: bool,
123
124 /// Whether the window should be set as fullscreen upon creation.
125 ///
126 /// The default is `None`.
127 pub fullscreen: Option<Fullscreen>,
128
129 /// The title of the window in the title bar.
130 ///
131 /// The default is `"winit window"`.
132 pub title: String,
133
134 /// Whether the window should be maximized upon creation.
135 ///
136 /// The default is `false`.
137 pub maximized: bool,
138
139 /// Whether the window should be immediately visible upon creation.
140 ///
141 /// The default is `true`.
142 pub visible: bool,
143
144 /// Whether the the window should be transparent. If this is true, writing colors
145 /// with alpha values different than `1.0` will produce a transparent window.
146 ///
147 /// The default is `false`.
148 pub transparent: bool,
149
150 /// Whether the window should have borders and bars.
151 ///
152 /// The default is `true`.
153 pub decorations: bool,
154
155 /// Whether the window should always be on top of other windows.
156 ///
157 /// The default is `false`.
158 pub always_on_top: bool,
159
160 /// The window icon.
161 ///
162 /// The default is `None`.
163 pub window_icon: Option<Icon>,
164}
165
166impl Default for WindowAttributes {
167 #[inline]
168 fn default() -> WindowAttributes {
169 WindowAttributes {
170 inner_size: None,
171 min_inner_size: None,
172 max_inner_size: None,
173 resizable: true,
174 title: "winit window".to_owned(),
175 maximized: false,
176 fullscreen: None,
177 visible: true,
178 transparent: false,
179 decorations: true,
180 always_on_top: false,
181 window_icon: None,
182 }
183 }
184}
185
186impl WindowBuilder {
187 /// Initializes a new `WindowBuilder` with default values.
188 #[inline]
189 pub fn new() -> Self {
190 Default::default()
191 }
192
193 /// Requests the window to be of specific dimensions.
194 ///
195 /// See [`Window::set_inner_size`] for details.
196 ///
197 /// [`Window::set_inner_size`]: crate::window::Window::set_inner_size
198 #[inline]
199 pub fn with_inner_size<S: Into<Size>>(mut self, size: S) -> Self {
200 self.window.inner_size = Some(size.into());
201 self
202 }
203
204 /// Sets a minimum dimension size for the window.
205 ///
206 /// See [`Window::set_min_inner_size`] for details.
207 ///
208 /// [`Window::set_min_inner_size`]: crate::window::Window::set_min_inner_size
209 #[inline]
210 pub fn with_min_inner_size<S: Into<Size>>(mut self, min_size: S) -> Self {
211 self.window.min_inner_size = Some(min_size.into());
212 self
213 }
214
215 /// Sets a maximum dimension size for the window.
216 ///
217 /// See [`Window::set_max_inner_size`] for details.
218 ///
219 /// [`Window::set_max_inner_size`]: crate::window::Window::set_max_inner_size
220 #[inline]
221 pub fn with_max_inner_size<S: Into<Size>>(mut self, max_size: S) -> Self {
222 self.window.max_inner_size = Some(max_size.into());
223 self
224 }
225
226 /// Sets whether the window is resizable or not.
227 ///
228 /// See [`Window::set_resizable`] for details.
229 ///
230 /// [`Window::set_resizable`]: crate::window::Window::set_resizable
231 #[inline]
232 pub fn with_resizable(mut self, resizable: bool) -> Self {
233 self.window.resizable = resizable;
234 self
235 }
236
237 /// Requests a specific title for the window.
238 ///
239 /// See [`Window::set_title`] for details.
240 ///
241 /// [`Window::set_title`]: crate::window::Window::set_title
242 #[inline]
243 pub fn with_title<T: Into<String>>(mut self, title: T) -> Self {
244 self.window.title = title.into();
245 self
246 }
247
248 /// Sets the window fullscreen state.
249 ///
250 /// See [`Window::set_fullscreen`] for details.
251 ///
252 /// [`Window::set_fullscreen`]: crate::window::Window::set_fullscreen
253 #[inline]
254 pub fn with_fullscreen(mut self, fullscreen: Option<Fullscreen>) -> Self {
255 self.window.fullscreen = fullscreen;
256 self
257 }
258
259 /// Requests maximized mode.
260 ///
261 /// See [`Window::set_maximized`] for details.
262 ///
263 /// [`Window::set_maximized`]: crate::window::Window::set_maximized
264 #[inline]
265 pub fn with_maximized(mut self, maximized: bool) -> Self {
266 self.window.maximized = maximized;
267 self
268 }
269
270 /// Sets whether the window will be initially hidden or visible.
271 ///
272 /// See [`Window::set_visible`] for details.
273 ///
274 /// [`Window::set_visible`]: crate::window::Window::set_visible
275 #[inline]
276 pub fn with_visible(mut self, visible: bool) -> Self {
277 self.window.visible = visible;
278 self
279 }
280
281 /// Sets whether the background of the window should be transparent.
282 #[inline]
283 pub fn with_transparent(mut self, transparent: bool) -> Self {
284 self.window.transparent = transparent;
285 self
286 }
287
288 /// Sets whether the window should have a border, a title bar, etc.
289 ///
290 /// See [`Window::set_decorations`] for details.
291 ///
292 /// [`Window::set_decorations`]: crate::window::Window::set_decorations
293 #[inline]
294 pub fn with_decorations(mut self, decorations: bool) -> Self {
295 self.window.decorations = decorations;
296 self
297 }
298
299 /// Sets whether or not the window will always be on top of other windows.
300 ///
301 /// See [`Window::set_always_on_top`] for details.
302 ///
303 /// [`Window::set_always_on_top`]: crate::window::Window::set_always_on_top
304 #[inline]
305 pub fn with_always_on_top(mut self, always_on_top: bool) -> Self {
306 self.window.always_on_top = always_on_top;
307 self
308 }
309
310 /// Sets the window icon.
311 ///
312 /// See [`Window::set_window_icon`] for details.
313 ///
314 /// [`Window::set_window_icon`]: crate::window::Window::set_window_icon
315 #[inline]
316 pub fn with_window_icon(mut self, window_icon: Option<Icon>) -> Self {
317 self.window.window_icon = window_icon;
318 self
319 }
320
321 /// Builds the window.
322 ///
323 /// Possible causes of error include denied permission, incompatible system, and lack of memory.
324 ///
325 /// Platform-specific behavior:
326 /// - **Web**: The window is created but not inserted into the web page automatically. Please
327 /// see the web platform module for more information.
328 #[inline]
329 pub fn build<T: 'static>(
330 self,
331 window_target: &EventLoopWindowTarget<T>,
332 ) -> Result<Window, OsError> {
333 platform_impl::Window::new(&window_target.p, self.window, self.platform_specific).map(
334 |window| {
335 window.request_redraw();
336 Window { window }
337 },
338 )
339 }
340}
341
342/// Base Window functions.
343impl Window {
344 /// Creates a new Window for platforms where this is appropriate.
345 ///
346 /// This function is equivalent to [`WindowBuilder::new().build(event_loop)`].
347 ///
348 /// Error should be very rare and only occur in case of permission denied, incompatible system,
349 /// out of memory, etc.
350 ///
351 /// Platform-specific behavior:
352 /// - **Web**: The window is created but not inserted into the web page automatically. Please
353 /// see the web platform module for more information.
354 ///
355 /// [`WindowBuilder::new().build(event_loop)`]: crate::window::WindowBuilder::build
356 #[inline]
357 pub fn new<T: 'static>(event_loop: &EventLoopWindowTarget<T>) -> Result<Window, OsError> {
358 let builder = WindowBuilder::new();
359 builder.build(event_loop)
360 }
361
362 /// Returns an identifier unique to the window.
363 #[inline]
364 pub fn id(&self) -> WindowId {
365 WindowId(self.window.id())
366 }
367
368 /// Returns the scale factor that can be used to map logical pixels to physical pixels, and vice versa.
369 ///
370 /// See the [`dpi`](crate::dpi) module for more information.
371 ///
372 /// Note that this value can change depending on user action (for example if the window is
373 /// moved to another screen); as such, tracking `WindowEvent::ScaleFactorChanged` events is
374 /// the most robust way to track the DPI you need to use to draw.
375 ///
376 /// ## Platform-specific
377 ///
378 /// - **X11:** This respects Xft.dpi, and can be overridden using the `WINIT_X11_SCALE_FACTOR` environment variable.
379 /// - **Android:** Always returns 1.0.
380 /// - **iOS:** Can only be called on the main thread. Returns the underlying `UIView`'s
381 /// [`contentScaleFactor`].
382 ///
383 /// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
384 #[inline]
385 pub fn scale_factor(&self) -> f64 {
386 self.window.scale_factor()
387 }
388
389 /// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS
390 /// events have been processed by the event loop.
391 ///
392 /// This is the **strongly encouraged** method of redrawing windows, as it can integrate with
393 /// OS-requested redraws (e.g. when a window gets resized).
394 ///
395 /// This function can cause `RedrawRequested` events to be emitted after `Event::MainEventsCleared`
396 /// but before `Event::NewEvents` if called in the following circumstances:
397 /// * While processing `MainEventsCleared`.
398 /// * While processing a `RedrawRequested` event that was sent during `MainEventsCleared` or any
399 /// directly subsequent `RedrawRequested` event.
400 ///
401 /// ## Platform-specific
402 ///
403 /// - **iOS:** Can only be called on the main thread.
404 /// - **Android:** Unsupported.
405 #[inline]
406 pub fn request_redraw(&self) {
407 self.window.request_redraw()
408 }
409}
410
411/// Position and size functions.
412impl Window {
413 /// Returns the position of the top-left hand corner of the window's client area relative to the
414 /// top-left hand corner of the desktop.
415 ///
416 /// The same conditions that apply to `outer_position` apply to this method.
417 ///
418 /// ## Platform-specific
419 ///
420 /// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
421 /// window's [safe area] in the screen space coordinate system.
422 /// - **Web:** Returns the top-left coordinates relative to the viewport. _Note: this returns the
423 /// same value as `outer_position`._
424 /// - **Android / Wayland:** Always returns [`NotSupportedError`].
425 ///
426 /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
427 #[inline]
428 pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
429 self.window.inner_position()
430 }
431
432 /// Returns the position of the top-left hand corner of the window relative to the
433 /// top-left hand corner of the desktop.
434 ///
435 /// Note that the top-left hand corner of the desktop is not necessarily the same as
436 /// the screen. If the user uses a desktop with multiple monitors, the top-left hand corner
437 /// of the desktop is the top-left hand corner of the monitor at the top-left of the desktop.
438 ///
439 /// The coordinates can be negative if the top-left hand corner of the window is outside
440 /// of the visible screen region.
441 ///
442 /// ## Platform-specific
443 ///
444 /// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
445 /// window in the screen space coordinate system.
446 /// - **Web:** Returns the top-left coordinates relative to the viewport.
447 /// - **Android / Wayland:** Always returns [`NotSupportedError`].
448 #[inline]
449 pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
450 self.window.outer_position()
451 }
452
453 /// Modifies the position of the window.
454 ///
455 /// See `outer_position` for more information about the coordinates. This automatically un-maximizes the
456 /// window if it's maximized.
457 ///
458 /// ## Platform-specific
459 ///
460 /// - **iOS:** Can only be called on the main thread. Sets the top left coordinates of the
461 /// window in the screen space coordinate system.
462 /// - **Web:** Sets the top-left coordinates relative to the viewport.
463 /// - **Android / Wayland:** Unsupported.
464 #[inline]
465 pub fn set_outer_position<P: Into<Position>>(&self, position: P) {
466 self.window.set_outer_position(position.into())
467 }
468
469 /// Returns the physical size of the window's client area.
470 ///
471 /// The client area is the content of the window, excluding the title bar and borders.
472 ///
473 /// ## Platform-specific
474 ///
475 /// - **iOS:** Can only be called on the main thread. Returns the `PhysicalSize` of the window's
476 /// [safe area] in screen space coordinates.
477 /// - **Web:** Returns the size of the canvas element.
478 ///
479 /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
480 #[inline]
481 pub fn inner_size(&self) -> PhysicalSize<u32> {
482 self.window.inner_size()
483 }
484
485 /// Modifies the inner size of the window.
486 ///
487 /// See `inner_size` for more information about the values. This automatically un-maximizes the
488 /// window if it's maximized.
489 ///
490 /// ## Platform-specific
491 ///
492 /// - **iOS / Android:** Unsupported.
493 /// - **Web:** Sets the size of the canvas element.
494 #[inline]
495 pub fn set_inner_size<S: Into<Size>>(&self, size: S) {
496 self.window.set_inner_size(size.into())
497 }
498
499 /// Returns the physical size of the entire window.
500 ///
501 /// These dimensions include the title bar and borders. If you don't want that (and you usually don't),
502 /// use `inner_size` instead.
503 ///
504 /// ## Platform-specific
505 ///
506 /// - **iOS:** Can only be called on the main thread. Returns the `PhysicalSize` of the window in
507 /// screen space coordinates.
508 /// - **Web:** Returns the size of the canvas element. _Note: this returns the same value as
509 /// `inner_size`._
510 #[inline]
511 pub fn outer_size(&self) -> PhysicalSize<u32> {
512 self.window.outer_size()
513 }
514
515 /// Sets a minimum dimension size for the window.
516 ///
517 /// ## Platform-specific
518 ///
519 /// - **iOS / Android / Web:** Unsupported.
520 #[inline]
521 pub fn set_min_inner_size<S: Into<Size>>(&self, min_size: Option<S>) {
522 self.window.set_min_inner_size(min_size.map(|s| s.into()))
523 }
524
525 /// Sets a maximum dimension size for the window.
526 ///
527 /// ## Platform-specific
528 ///
529 /// - **iOS / Andraid / Web:** Unsupported.
530 #[inline]
531 pub fn set_max_inner_size<S: Into<Size>>(&self, max_size: Option<S>) {
532 self.window.set_max_inner_size(max_size.map(|s| s.into()))
533 }
534}
535
536/// Misc. attribute functions.
537impl Window {
538 /// Modifies the title of the window.
539 ///
540 /// ## Platform-specific
541 ///
542 /// - **iOS / Android:** Unsupported.
543 #[inline]
544 pub fn set_title(&self, title: &str) {
545 self.window.set_title(title)
546 }
547
548 /// Modifies the window's visibility.
549 ///
550 /// If `false`, this will hide the window. If `true`, this will show the window.
551 /// ## Platform-specific
552 ///
553 /// - **Android / Wayland / Web:** Unsupported.
554 /// - **iOS:** Can only be called on the main thread.
555 #[inline]
556 pub fn set_visible(&self, visible: bool) {
557 self.window.set_visible(visible)
558 }
559
560 /// Sets whether the window is resizable or not.
561 ///
562 /// Note that making the window unresizable doesn't exempt you from handling `Resized`, as that event can still be
563 /// triggered by DPI scaling, entering fullscreen mode, etc.
564 ///
565 /// ## Platform-specific
566 ///
567 /// This only has an effect on desktop platforms.
568 ///
569 /// Due to a bug in XFCE, this has no effect on Xfwm.
570 ///
571 /// ## Platform-specific
572 ///
573 /// - **iOS / Android / Web:** Unsupported.
574 #[inline]
575 pub fn set_resizable(&self, resizable: bool) {
576 self.window.set_resizable(resizable)
577 }
578
579 /// Sets the window to minimized or back
580 ///
581 /// ## Platform-specific
582 ///
583 /// - **iOS / Android / Web:** Unsupported.
584 /// - **Wayland:** Un-minimize is unsupported.
585 #[inline]
586 pub fn set_minimized(&self, minimized: bool) {
587 self.window.set_minimized(minimized);
588 }
589
590 /// Sets the window to maximized or back.
591 ///
592 /// ## Platform-specific
593 ///
594 /// - **iOS / Android / Web:** Unsupported.
595 #[inline]
596 pub fn set_maximized(&self, maximized: bool) {
597 self.window.set_maximized(maximized)
598 }
599
600 /// Sets the window to fullscreen or back.
601 ///
602 /// ## Platform-specific
603 ///
604 /// - **macOS:** `Fullscreen::Exclusive` provides true exclusive mode with a
605 /// video mode change. *Caveat!* macOS doesn't provide task switching (or
606 /// spaces!) while in exclusive fullscreen mode. This mode should be used
607 /// when a video mode change is desired, but for a better user experience,
608 /// borderless fullscreen might be preferred.
609 ///
610 /// `Fullscreen::Borderless` provides a borderless fullscreen window on a
611 /// separate space. This is the idiomatic way for fullscreen games to work
612 /// on macOS. See `WindowExtMacOs::set_simple_fullscreen` if
613 /// separate spaces are not preferred.
614 ///
615 /// The dock and the menu bar are always disabled in fullscreen mode.
616 /// - **iOS:** Can only be called on the main thread.
617 /// - **Wayland:** Does not support exclusive fullscreen mode.
618 /// - **Windows:** Screen saver is disabled in fullscreen mode.
619 /// - **Android:** Unsupported.
620 #[inline]
621 pub fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
622 self.window.set_fullscreen(fullscreen)
623 }
624
625 /// Gets the window's current fullscreen state.
626 ///
627 /// ## Platform-specific
628 ///
629 /// - **iOS:** Can only be called on the main thread.
630 /// - **Android:** Will always return `None`.
631 #[inline]
632 pub fn fullscreen(&self) -> Option<Fullscreen> {
633 self.window.fullscreen()
634 }
635
636 /// Turn window decorations on or off.
637 ///
638 /// ## Platform-specific
639 ///
640 /// - **iOS / Android / Web:** Unsupported.
641 ///
642 /// [`setPrefersStatusBarHidden`]: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc
643 #[inline]
644 pub fn set_decorations(&self, decorations: bool) {
645 self.window.set_decorations(decorations)
646 }
647
648 /// Change whether or not the window will always be on top of other windows.
649 ///
650 /// ## Platform-specific
651 ///
652 /// - **iOS / Android / Web / Wayland:** Unsupported.
653 #[inline]
654 pub fn set_always_on_top(&self, always_on_top: bool) {
655 self.window.set_always_on_top(always_on_top)
656 }
657
658 /// Sets the window icon. On Windows and X11, this is typically the small icon in the top-left
659 /// corner of the titlebar.
660 ///
661 /// ## Platform-specific
662 ///
663 /// - **iOS / Android / Web / Wayland / macOS:** Unsupported.
664 ///
665 /// On Windows, this sets `ICON_SMALL`. The base size for a window icon is 16x16, but it's
666 /// recommended to account for screen scaling and pick a multiple of that, i.e. 32x32.
667 ///
668 /// X11 has no universal guidelines for icon sizes, so you're at the whims of the WM. That
669 /// said, it's usually in the same ballpark as on Windows.
670 #[inline]
671 pub fn set_window_icon(&self, window_icon: Option<Icon>) {
672 self.window.set_window_icon(window_icon)
673 }
674
675 /// Sets location of IME candidate box in client area coordinates relative to the top left.
676 ///
677 /// ## Platform-specific
678 ///
679 /// - **iOS / Android / Web / Wayland / Windows:** Unsupported.
680 #[inline]
681 pub fn set_ime_position<P: Into<Position>>(&self, position: P) {
682 self.window.set_ime_position(position.into())
683 }
684}
685
686/// Cursor functions.
687impl Window {
688 /// Modifies the cursor icon of the window.
689 ///
690 /// ## Platform-specific
691 ///
692 /// - **iOS / Android:** Unsupported.
693 #[inline]
694 pub fn set_cursor_icon(&self, cursor: CursorIcon) {
695 self.window.set_cursor_icon(cursor);
696 }
697
698 /// Changes the position of the cursor in window coordinates.
699 ///
700 /// ## Platform-specific
701 ///
702 /// - **iOS / Android / Web / Wayland:** Always returns an [`ExternalError::NotSupported`].
703 #[inline]
704 pub fn set_cursor_position<P: Into<Position>>(&self, position: P) -> Result<(), ExternalError> {
705 self.window.set_cursor_position(position.into())
706 }
707
708 /// Grabs the cursor, preventing it from leaving the window.
709 ///
710 /// ## Platform-specific
711 ///
712 /// - **macOS / Wayland:** This locks the cursor in a fixed location, which looks visually awkward.
713 /// - **iOS / Android / Web:** Always returns an [`ExternalError::NotSupported`].
714 #[inline]
715 pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
716 self.window.set_cursor_grab(grab)
717 }
718
719 /// Modifies the cursor's visibility.
720 ///
721 /// If `false`, this will hide the cursor. If `true`, this will show the cursor.
722 ///
723 /// ## Platform-specific
724 ///
725 /// - **Windows:** The cursor is only hidden within the confines of the window.
726 /// - **X11:** The cursor is only hidden within the confines of the window.
727 /// - **Wayland:** The cursor is only hidden within the confines of the window.
728 /// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is
729 /// outside of the window.
730 /// - **iOS / Android:** Unsupported.
731 #[inline]
732 pub fn set_cursor_visible(&self, visible: bool) {
733 self.window.set_cursor_visible(visible)
734 }
735}
736
737/// Monitor info functions.
738impl Window {
739 /// Returns the monitor on which the window currently resides
740 ///
741 /// ## Platform-specific
742 ///
743 /// **iOS:** Can only be called on the main thread.
744 #[inline]
745 pub fn current_monitor(&self) -> MonitorHandle {
746 self.window.current_monitor()
747 }
748
749 /// Returns the list of all the monitors available on the system.
750 ///
751 /// This is the same as `EventLoopWindowTarget::available_monitors`, and is provided for convenience.
752 ///
753 /// ## Platform-specific
754 ///
755 /// **iOS:** Can only be called on the main thread.
756 #[inline]
757 pub fn available_monitors(&self) -> impl Iterator<Item = MonitorHandle> {
758 self.window
759 .available_monitors()
760 .into_iter()
761 .map(|inner| MonitorHandle { inner })
762 }
763
764 /// Returns the primary monitor of the system.
765 ///
766 /// This is the same as `EventLoopWindowTarget::primary_monitor`, and is provided for convenience.
767 ///
768 /// ## Platform-specific
769 ///
770 /// **iOS:** Can only be called on the main thread.
771 #[inline]
772 pub fn primary_monitor(&self) -> MonitorHandle {
773 MonitorHandle {
774 inner: self.window.primary_monitor(),
775 }
776 }
777}
778
779unsafe impl raw_window_handle::HasRawWindowHandle for Window {
780 fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
781 self.window.raw_window_handle()
782 }
783}
784
785/// Describes the appearance of the mouse cursor.
786#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
787#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
788pub enum CursorIcon {
789 /// The platform-dependent default cursor.
790 Default,
791 /// A simple crosshair.
792 Crosshair,
793 /// A hand (often used to indicate links in web browsers).
794 Hand,
795 /// Self explanatory.
796 Arrow,
797 /// Indicates something is to be moved.
798 Move,
799 /// Indicates text that may be selected or edited.
800 Text,
801 /// Program busy indicator.
802 Wait,
803 /// Help indicator (often rendered as a "?")
804 Help,
805 /// Progress indicator. Shows that processing is being done. But in contrast
806 /// with "Wait" the user may still interact with the program. Often rendered
807 /// as a spinning beach ball, or an arrow with a watch or hourglass.
808 Progress,
809
810 /// Cursor showing that something cannot be done.
811 NotAllowed,
812 ContextMenu,
813 Cell,
814 VerticalText,
815 Alias,
816 Copy,
817 NoDrop,
818 /// Indicates something can be grabbed.
819 Grab,
820 /// Indicates something is grabbed.
821 Grabbing,
822 AllScroll,
823 ZoomIn,
824 ZoomOut,
825
826 /// Indicate that some edge is to be moved. For example, the 'SeResize' cursor
827 /// is used when the movement starts from the south-east corner of the box.
828 EResize,
829 NResize,
830 NeResize,
831 NwResize,
832 SResize,
833 SeResize,
834 SwResize,
835 WResize,
836 EwResize,
837 NsResize,
838 NeswResize,
839 NwseResize,
840 ColResize,
841 RowResize,
842}
843
844impl Default for CursorIcon {
845 fn default() -> Self {
846 CursorIcon::Default
847 }
848}
849
850#[derive(Clone, Debug, PartialEq)]
851pub enum Fullscreen {
852 Exclusive(VideoMode),
853 Borderless(MonitorHandle),
854}
855
856#[derive(Clone, Debug, PartialEq)]
857pub enum Theme {
858 Light,
859 Dark,
860}