async_winit/
window.rs

1/*
2
3`async-winit` is free software: you can redistribute it and/or modify it under the terms of one of
4the following licenses:
5
6* GNU Lesser General Public License as published by the Free Software Foundation, either
7  version 3 of the License, or (at your option) any later version.
8* Mozilla Public License as published by the Mozilla Foundation, version 2.
9
10`async-winit` is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
11the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
12Public License and the Patron License for more details.
13
14You should have received a copy of the GNU Lesser General Public License and the Mozilla
15Public License along with `async-winit`. If not, see <https://www.gnu.org/licenses/>.
16
17*/
18
19// This file is partially derived from `winit`, which was originally created by Pierre Krieger and
20// contributers. It was originally released under the MIT license.
21
22//! Window code adapted for `async` usage.
23
24use crate::dpi::{Position, Size};
25use crate::error::OsError;
26use crate::handler::Handler;
27use crate::oneoff::oneoff;
28use crate::reactor::{EventLoopOp, Reactor};
29use crate::sync::{ThreadSafety, __private::Rc};
30
31pub(crate) mod registration;
32
33use registration::Registration;
34
35use winit::dpi::{PhysicalPosition, PhysicalSize};
36use winit::error::{ExternalError, NotSupportedError};
37use winit::event::DeviceId;
38use winit::monitor::MonitorHandle;
39
40#[doc(inline)]
41pub use winit::window::{
42    CursorGrabMode, CursorIcon, Fullscreen, Icon, ImePurpose, ResizeDirection, Theme,
43    UserAttentionType, WindowButtons, WindowLevel,
44};
45
46/// Attributes to use when creating a window.
47#[derive(Debug, Clone)]
48pub struct WindowAttributes {
49    pub inner_size: Option<Size>,
50    pub min_inner_size: Option<Size>,
51    pub max_inner_size: Option<Size>,
52    pub position: Option<Position>,
53    pub resizable: bool,
54    pub enabled_buttons: WindowButtons,
55    pub title: String,
56    pub fullscreen: Option<Fullscreen>,
57    pub maximized: bool,
58    pub visible: bool,
59    pub transparent: bool,
60    pub decorations: bool,
61    pub window_icon: Option<Icon>,
62    pub preferred_theme: Option<Theme>,
63    pub resize_increments: Option<Size>,
64    pub content_protected: bool,
65    pub window_level: WindowLevel,
66    pub active: bool,
67}
68
69impl Default for WindowAttributes {
70    #[inline]
71    fn default() -> WindowAttributes {
72        WindowAttributes {
73            inner_size: None,
74            min_inner_size: None,
75            max_inner_size: None,
76            position: None,
77            resizable: true,
78            enabled_buttons: WindowButtons::all(),
79            title: "winit window".to_owned(),
80            maximized: false,
81            fullscreen: None,
82            visible: true,
83            transparent: false,
84            decorations: true,
85            window_level: Default::default(),
86            window_icon: None,
87            preferred_theme: None,
88            resize_increments: None,
89            content_protected: false,
90            active: true,
91        }
92    }
93}
94
95/// A builder to use to create windows.
96#[derive(Default)]
97pub struct WindowBuilder {
98    window: WindowAttributes,
99    pub(crate) platform: crate::platform::PlatformSpecific,
100}
101
102impl WindowBuilder {
103    /// Create a new window builder.
104    pub fn new() -> WindowBuilder {
105        WindowBuilder::default()
106    }
107
108    pub fn attributes(&self) -> &WindowAttributes {
109        &self.window
110    }
111
112    /// Get the current window attributes.
113    pub fn window_attributes(&self) -> &WindowAttributes {
114        &self.window
115    }
116
117    /// Requests the window to be of specific dimensions.
118    ///
119    /// If this is not set, some platform-specific dimensions will be used.
120    ///
121    /// See [`Window::set_inner_size`] for details.
122    #[inline]
123    pub fn with_inner_size<S: Into<Size>>(mut self, size: S) -> Self {
124        self.window.inner_size = Some(size.into());
125        self
126    }
127
128    /// Sets the minimum dimensions a window can have.
129    ///
130    /// If this is not set, the window will have no minimum dimensions (aside
131    /// from reserved).
132    ///
133    /// See [`Window::set_min_inner_size`] for details.
134    #[inline]
135    pub fn with_min_inner_size<S: Into<Size>>(mut self, min_size: S) -> Self {
136        self.window.min_inner_size = Some(min_size.into());
137        self
138    }
139
140    /// Sets the maximum dimensions a window can have.
141    ///
142    /// If this is not set, the window will have no maximum or will be set to
143    /// the primary monitor's dimensions by the platform.
144    ///
145    /// See [`Window::set_max_inner_size`] for details.
146    #[inline]
147    pub fn with_max_inner_size<S: Into<Size>>(mut self, max_size: S) -> Self {
148        self.window.max_inner_size = Some(max_size.into());
149        self
150    }
151
152    /// Sets a desired initial position for the window.
153    ///
154    /// If this is not set, some platform-specific position will be chosen.
155    ///
156    /// See [`Window::set_outer_position`] for details.
157    ///
158    /// ## Platform-specific
159    ///
160    /// - **macOS:** The top left corner position of the window content, the
161    ///   window's "inner" position. The window title bar will be placed above
162    ///   it. The window will be positioned such that it fits on screen,
163    ///   maintaining set `inner_size` if any.
164    ///   If you need to precisely position the top left corner of the whole
165    ///   window you have to use [`Window::set_outer_position`] after creating
166    ///   the window.
167    /// - **Windows:** The top left corner position of the window title bar,
168    ///   the window's "outer" position.
169    ///   There may be a small gap between this position and the window due to
170    ///   the specifics of the Window Manager.
171    /// - **X11:** The top left corner of the window, the window's "outer"
172    ///   position.
173    /// - **Others:** Ignored.
174    #[inline]
175    pub fn with_position<P: Into<Position>>(mut self, position: P) -> Self {
176        self.window.position = Some(position.into());
177        self
178    }
179
180    /// Sets whether the window is resizable or not.
181    ///
182    /// The default is `true`.
183    ///
184    /// See [`Window::set_resizable`] for details.
185    #[inline]
186    pub fn with_resizable(mut self, resizable: bool) -> Self {
187        self.window.resizable = resizable;
188        self
189    }
190
191    /// Sets the enabled window buttons.
192    ///
193    /// The default is [`WindowButtons::all`]
194    ///
195    /// See `Window::set_enabled_buttons` for details.
196    #[inline]
197    pub fn with_enabled_buttons(mut self, buttons: WindowButtons) -> Self {
198        self.window.enabled_buttons = buttons;
199        self
200    }
201
202    /// Sets the initial title of the window in the title bar.
203    ///
204    /// The default is `"winit window"`.
205    ///
206    /// See [`Window::set_title`] for details.
207    #[inline]
208    pub fn with_title<T: Into<String>>(mut self, title: T) -> Self {
209        self.window.title = title.into();
210        self
211    }
212
213    /// Sets whether the window should be put into fullscreen upon creation.
214    ///
215    /// The default is `None`.
216    ///
217    /// See [`Window::set_fullscreen`] for details.
218    #[inline]
219    pub fn with_fullscreen(mut self, fullscreen: Option<Fullscreen>) -> Self {
220        self.window.fullscreen = fullscreen;
221        self
222    }
223
224    /// Request that the window is maximized upon creation.
225    ///
226    /// The default is `false`.
227    ///
228    /// See [`Window::set_maximized`] for details.
229    #[inline]
230    pub fn with_maximized(mut self, maximized: bool) -> Self {
231        self.window.maximized = maximized;
232        self
233    }
234
235    /// Sets whether the window will be initially visible or hidden.
236    ///
237    /// The default is to show the window.
238    ///
239    /// See [`Window::set_visible`] for details.
240    #[inline]
241    pub fn with_visible(mut self, visible: bool) -> Self {
242        self.window.visible = visible;
243        self
244    }
245
246    /// Sets whether the background of the window should be transparent.
247    ///
248    /// If this is `true`, writing colors with alpha values different than
249    /// `1.0` will produce a transparent window. On some platforms this
250    /// is more of a hint for the system and you'd still have the alpha
251    /// buffer. To control it see [`Window::set_transparent`].
252    ///
253    /// The default is `false`.
254    #[inline]
255    pub fn with_transparent(mut self, transparent: bool) -> Self {
256        self.window.transparent = transparent;
257        self
258    }
259
260    /// Get whether the window will support transparency.
261    #[inline]
262    pub fn transparent(&self) -> bool {
263        self.window.transparent
264    }
265
266    /// Sets whether the window should have a border, a title bar, etc.
267    ///
268    /// The default is `true`.
269    ///
270    /// See [`Window::set_decorations`] for details.
271    #[inline]
272    pub fn with_decorations(mut self, decorations: bool) -> Self {
273        self.window.decorations = decorations;
274        self
275    }
276
277    /// Sets the window level.
278    ///
279    /// This is just a hint to the OS, and the system could ignore it.
280    ///
281    /// The default is [`WindowLevel::Normal`].
282    ///
283    /// See [`WindowLevel`] for details.
284    #[inline]
285    pub fn with_window_level(mut self, level: WindowLevel) -> Self {
286        self.window.window_level = level;
287        self
288    }
289
290    /// Sets the window icon.
291    ///
292    /// The default is `None`.
293    ///
294    /// See [`Window::set_window_icon`] for details.
295    #[inline]
296    pub fn with_window_icon(mut self, window_icon: Option<Icon>) -> Self {
297        self.window.window_icon = window_icon;
298        self
299    }
300
301    /// Sets a specific theme for the window.
302    ///
303    /// If `None` is provided, the window will use the system theme.
304    ///
305    /// The default is `None`.
306    ///
307    /// ## Platform-specific
308    ///
309    /// - **macOS:** This is an app-wide setting.
310    /// - **Wayland:** This control only CSD. You can also use `WINIT_WAYLAND_CSD_THEME` env variable to set the theme.
311    ///   Possible values for env variable are: "dark" and light".
312    /// - **x11:** Build window with `_GTK_THEME_VARIANT` hint set to `dark` or `light`.
313    /// - **iOS / Android / Web / x11 / Orbital:** Ignored.
314    #[inline]
315    pub fn with_theme(mut self, theme: Option<Theme>) -> Self {
316        self.window.preferred_theme = theme;
317        self
318    }
319
320    /// Build window with resize increments hint.
321    ///
322    /// The default is `None`.
323    ///
324    /// See [`Window::set_resize_increments`] for details.
325    #[inline]
326    pub fn with_resize_increments<S: Into<Size>>(mut self, resize_increments: S) -> Self {
327        self.window.resize_increments = Some(resize_increments.into());
328        self
329    }
330
331    /// Prevents the window contents from being captured by other apps.
332    ///
333    /// The default is `false`.
334    ///
335    /// ## Platform-specific
336    ///
337    /// - **macOS**: if `false`, [`NSWindowSharingNone`] is used but doesn't completely
338    /// prevent all apps from reading the window content, for instance, QuickTime.
339    /// - **iOS / Android / Web / x11 / Orbital:** Ignored.
340    ///
341    /// [`NSWindowSharingNone`]: https://developer.apple.com/documentation/appkit/nswindowsharingtype/nswindowsharingnone
342    #[inline]
343    pub fn with_content_protected(mut self, protected: bool) -> Self {
344        self.window.content_protected = protected;
345        self
346    }
347
348    /// Whether the window will be initially focused or not.
349    ///
350    /// The window should be assumed as not focused by default
351    /// following by the [`WindowEvent::Focused`].
352    ///
353    /// ## Platform-specific:
354    ///
355    /// **Android / iOS / X11 / Wayland / Orbital:** Unsupported.
356    ///
357    /// [`WindowEvent::Focused`]: crate::event::WindowEvent::Focused.
358    #[inline]
359    pub fn with_active(mut self, active: bool) -> WindowBuilder {
360        self.window.active = active;
361        self
362    }
363
364    /// Build a new window.
365    pub async fn build<TS: ThreadSafety>(self) -> Result<Window<TS>, OsError> {
366        let (tx, rx) = oneoff();
367        let reactor = TS::get_reactor();
368        reactor
369            .push_event_loop_op(EventLoopOp::BuildWindow {
370                builder: Box::new(self),
371                waker: tx,
372            })
373            .await;
374
375        let inner = rx.recv().await?;
376
377        // Insert the window into the global window map.
378        let registration = reactor.insert_window(inner.id());
379
380        Ok(Window {
381            inner: TS::Rc::new(inner),
382            registration,
383            reactor,
384        })
385    }
386
387    pub(crate) fn into_winit_builder(self) -> winit::window::WindowBuilder {
388        let mut builder = winit::window::WindowBuilder::new();
389
390        if let Some(size) = self.window.inner_size {
391            builder = builder.with_inner_size(size);
392        }
393
394        if let Some(size) = self.window.min_inner_size {
395            builder = builder.with_min_inner_size(size);
396        }
397
398        if let Some(size) = self.window.max_inner_size {
399            builder = builder.with_max_inner_size(size);
400        }
401
402        if let Some(position) = self.window.position {
403            builder = builder.with_position(position);
404        }
405
406        builder = builder
407            .with_resizable(self.window.resizable)
408            .with_enabled_buttons(self.window.enabled_buttons)
409            .with_title(&self.window.title)
410            .with_fullscreen(self.window.fullscreen.clone())
411            .with_maximized(self.window.maximized)
412            .with_visible(self.window.visible)
413            .with_transparent(self.window.transparent)
414            .with_decorations(self.window.decorations);
415
416        if let Some(icon) = self.window.window_icon.clone() {
417            builder = builder.with_window_icon(Some(icon));
418        }
419
420        builder = builder.with_theme(self.window.preferred_theme);
421
422        if let Some(size) = self.window.resize_increments {
423            builder = builder.with_resize_increments(size);
424        }
425
426        builder = builder
427            .with_content_protected(self.window.content_protected)
428            .with_window_level(self.window.window_level)
429            .with_active(self.window.active);
430
431        builder = self.platform.apply_to(builder);
432
433        builder
434    }
435}
436
437/// A window.
438#[derive(Clone)]
439pub struct Window<TS: ThreadSafety> {
440    /// Underlying window.
441    inner: TS::Rc<winit::window::Window>,
442
443    /// Registration for the window.
444    registration: TS::Rc<Registration<TS>>,
445
446    /// Underlying window reactor.
447    reactor: TS::Rc<Reactor<TS>>,
448}
449
450impl<TS: ThreadSafety> Drop for Window<TS> {
451    fn drop(&mut self) {
452        self.reactor.remove_window(self.inner.id());
453    }
454}
455
456unsafe impl<TS: ThreadSafety> raw_window_handle::HasRawDisplayHandle for Window<TS> {
457    fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle {
458        self.inner.raw_display_handle()
459    }
460}
461
462unsafe impl<TS: ThreadSafety> raw_window_handle::HasRawWindowHandle for Window<TS> {
463    fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
464        self.inner.raw_window_handle()
465    }
466}
467
468impl<TS: ThreadSafety> Window<TS> {
469    /// Create a new window.
470    pub async fn new() -> Result<Window<TS>, OsError> {
471        WindowBuilder::new().build().await
472    }
473
474    /// Get a reference to the underlying window.
475    pub fn window(&self) -> &winit::window::Window {
476        &self.inner
477    }
478
479    /// Get the ID of the window.
480    pub fn id(&self) -> winit::window::WindowId {
481        self.inner.id()
482    }
483
484    /// Get the scale factor of the window.
485    pub fn scale_factor(&self) -> f64 {
486        self.inner.scale_factor()
487    }
488
489    /// Request a redraw.
490    pub fn request_redraw(&self) {
491        self.inner.request_redraw();
492    }
493}
494
495impl<TS: ThreadSafety> Window<TS> {
496    /// Get the inner position of the window.
497    pub async fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
498        let (tx, rx) = oneoff();
499        self.reactor
500            .push_event_loop_op(EventLoopOp::InnerPosition {
501                window: self.inner.clone(),
502                waker: tx,
503            })
504            .await;
505
506        rx.recv().await
507    }
508
509    /// Get the outer position of the window.
510    pub async fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
511        let (tx, rx) = oneoff();
512        self.reactor
513            .push_event_loop_op(EventLoopOp::OuterPosition {
514                window: self.inner.clone(),
515                waker: tx,
516            })
517            .await;
518
519        rx.recv().await
520    }
521
522    /// Set the outer position of the window.
523    pub async fn set_outer_position(&self, position: impl Into<Position>) {
524        let (tx, rx) = oneoff();
525        self.reactor
526            .push_event_loop_op(EventLoopOp::SetOuterPosition {
527                window: self.inner.clone(),
528                position: position.into(),
529                waker: tx,
530            })
531            .await;
532
533        rx.recv().await
534    }
535
536    /// Get the inner size of the window.
537    pub async fn inner_size(&self) -> PhysicalSize<u32> {
538        let (tx, rx) = oneoff();
539        self.reactor
540            .push_event_loop_op(EventLoopOp::InnerSize {
541                window: self.inner.clone(),
542                waker: tx,
543            })
544            .await;
545
546        rx.recv().await
547    }
548
549    /// Get the outer size of the window.
550    pub async fn outer_size(&self) -> PhysicalSize<u32> {
551        let (tx, rx) = oneoff();
552        self.reactor
553            .push_event_loop_op(EventLoopOp::OuterSize {
554                window: self.inner.clone(),
555                waker: tx,
556            })
557            .await;
558
559        rx.recv().await
560    }
561
562    /// Set the inner size of the window.
563    pub async fn set_inner_size(&self, size: impl Into<Size>) {
564        let (tx, rx) = oneoff();
565        self.reactor
566            .push_event_loop_op(EventLoopOp::SetInnerSize {
567                window: self.inner.clone(),
568                size: size.into(),
569                waker: tx,
570            })
571            .await;
572
573        rx.recv().await
574    }
575
576    /// Set the minimum inner size of the window.
577    pub async fn set_min_inner_size(&self, size: impl Into<Option<Size>>) {
578        let (tx, rx) = oneoff();
579        self.reactor
580            .push_event_loop_op(EventLoopOp::SetMinInnerSize {
581                window: self.inner.clone(),
582                size: size.into(),
583                waker: tx,
584            })
585            .await;
586
587        rx.recv().await
588    }
589
590    /// Set the maximum inner size of the window.
591    pub async fn set_max_inner_size(&self, size: impl Into<Option<Size>>) {
592        let (tx, rx) = oneoff();
593        self.reactor
594            .push_event_loop_op(EventLoopOp::SetMaxInnerSize {
595                window: self.inner.clone(),
596                size: size.into(),
597                waker: tx,
598            })
599            .await;
600
601        rx.recv().await
602    }
603
604    /// Get the resize increments of the window.
605    pub async fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
606        let (tx, rx) = oneoff();
607        self.reactor
608            .push_event_loop_op(EventLoopOp::ResizeIncrements {
609                window: self.inner.clone(),
610                waker: tx,
611            })
612            .await;
613
614        rx.recv().await
615    }
616
617    /// Set the resize increments of the window.
618    pub async fn set_resize_increments(&self, size: impl Into<Option<Size>>) {
619        let (tx, rx) = oneoff();
620        self.reactor
621            .push_event_loop_op(EventLoopOp::SetResizeIncrements {
622                window: self.inner.clone(),
623                size: size.into(),
624                waker: tx,
625            })
626            .await;
627
628        rx.recv().await
629    }
630
631    /// Set the title of the window.
632    pub async fn set_title(&self, title: impl Into<String>) {
633        let (tx, rx) = oneoff();
634        self.reactor
635            .push_event_loop_op(EventLoopOp::SetTitle {
636                window: self.inner.clone(),
637                title: title.into(),
638                waker: tx,
639            })
640            .await;
641
642        rx.recv().await
643    }
644
645    /// Set whether the window is visible.
646    pub async fn set_visible(&self, visible: bool) {
647        let (tx, rx) = oneoff();
648        self.reactor
649            .push_event_loop_op(EventLoopOp::SetVisible {
650                window: self.inner.clone(),
651                visible,
652                waker: tx,
653            })
654            .await;
655
656        rx.recv().await
657    }
658
659    /// Get the window's visibility.
660    pub async fn is_visible(&self) -> Option<bool> {
661        let (tx, rx) = oneoff();
662        self.reactor
663            .push_event_loop_op(EventLoopOp::Visible {
664                window: self.inner.clone(),
665                waker: tx,
666            })
667            .await;
668
669        rx.recv().await
670    }
671
672    /// Set the window's transparency.
673    pub async fn set_transparent(&self, transparent: bool) {
674        let (tx, rx) = oneoff();
675        self.reactor
676            .push_event_loop_op(EventLoopOp::SetTransparent {
677                window: self.inner.clone(),
678                transparent,
679                waker: tx,
680            })
681            .await;
682
683        rx.recv().await
684    }
685
686    /// Set the window's resizable property.
687    pub async fn set_resizable(&self, resizable: bool) {
688        let (tx, rx) = oneoff();
689        self.reactor
690            .push_event_loop_op(EventLoopOp::SetResizable {
691                window: self.inner.clone(),
692                resizable,
693                waker: tx,
694            })
695            .await;
696
697        rx.recv().await
698    }
699
700    /// Get the window's resizable property.
701    pub async fn is_resizable(&self) -> bool {
702        let (tx, rx) = oneoff();
703        self.reactor
704            .push_event_loop_op(EventLoopOp::Resizable {
705                window: self.inner.clone(),
706                waker: tx,
707            })
708            .await;
709
710        rx.recv().await
711    }
712
713    /// Set the window's minimization.
714    pub async fn set_minimized(&self, minimized: bool) {
715        let (tx, rx) = oneoff();
716        self.reactor
717            .push_event_loop_op(EventLoopOp::SetMinimized {
718                window: self.inner.clone(),
719                minimized,
720                waker: tx,
721            })
722            .await;
723
724        rx.recv().await
725    }
726
727    /// Get the window's minimization.
728    pub async fn is_minimized(&self) -> Option<bool> {
729        let (tx, rx) = oneoff();
730        self.reactor
731            .push_event_loop_op(EventLoopOp::Minimized {
732                window: self.inner.clone(),
733                waker: tx,
734            })
735            .await;
736
737        rx.recv().await
738    }
739
740    /// Set the window's maximization.
741    pub async fn set_maximized(&self, maximized: bool) {
742        let (tx, rx) = oneoff();
743        self.reactor
744            .push_event_loop_op(EventLoopOp::SetMaximized {
745                window: self.inner.clone(),
746                maximized,
747                waker: tx,
748            })
749            .await;
750
751        rx.recv().await
752    }
753
754    /// Get the window's maximization.
755    pub async fn is_maximized(&self) -> bool {
756        let (tx, rx) = oneoff();
757        self.reactor
758            .push_event_loop_op(EventLoopOp::Maximized {
759                window: self.inner.clone(),
760                waker: tx,
761            })
762            .await;
763
764        rx.recv().await
765    }
766
767    /// Set the window's fullscreen state.
768    pub async fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
769        let (tx, rx) = oneoff();
770        self.reactor
771            .push_event_loop_op(EventLoopOp::SetFullscreen {
772                window: self.inner.clone(),
773                fullscreen,
774                waker: tx,
775            })
776            .await;
777
778        rx.recv().await
779    }
780
781    /// Get the fullscreen state of the window.
782    pub async fn fullscreen(&self) -> Option<Fullscreen> {
783        let (tx, rx) = oneoff();
784        self.reactor
785            .push_event_loop_op(EventLoopOp::Fullscreen {
786                window: self.inner.clone(),
787                waker: tx,
788            })
789            .await;
790
791        rx.recv().await
792    }
793
794    /// Set the window's decorations.
795    pub async fn set_decorations(&self, decorations: bool) {
796        let (tx, rx) = oneoff();
797        self.reactor
798            .push_event_loop_op(EventLoopOp::SetDecorated {
799                window: self.inner.clone(),
800                decorated: decorations,
801                waker: tx,
802            })
803            .await;
804
805        rx.recv().await
806    }
807
808    /// Get the window's decorations.
809    pub async fn is_decorated(&self) -> bool {
810        let (tx, rx) = oneoff();
811        self.reactor
812            .push_event_loop_op(EventLoopOp::Decorated {
813                window: self.inner.clone(),
814                waker: tx,
815            })
816            .await;
817
818        rx.recv().await
819    }
820
821    /// Set the window level.
822    pub async fn set_window_level(&self, level: WindowLevel) {
823        let (tx, rx) = oneoff();
824        self.reactor
825            .push_event_loop_op(EventLoopOp::SetWindowLevel {
826                window: self.inner.clone(),
827                level,
828                waker: tx,
829            })
830            .await;
831
832        rx.recv().await
833    }
834
835    /// Set the window icon.
836    pub async fn set_window_icon(&self, icon: Option<Icon>) {
837        let (tx, rx) = oneoff();
838        self.reactor
839            .push_event_loop_op(EventLoopOp::SetWindowIcon {
840                window: self.inner.clone(),
841                icon,
842                waker: tx,
843            })
844            .await;
845
846        rx.recv().await
847    }
848
849    /// Set the IME position.
850    pub async fn set_ime_position(&self, posn: impl Into<Position>) {
851        let (tx, rx) = oneoff();
852        self.reactor
853            .push_event_loop_op(EventLoopOp::SetImePosition {
854                window: self.inner.clone(),
855                position: posn.into(),
856                waker: tx,
857            })
858            .await;
859
860        rx.recv().await
861    }
862
863    /// Set whether IME is allowed.
864    pub async fn set_ime_allowed(&self, allowed: bool) {
865        let (tx, rx) = oneoff();
866        self.reactor
867            .push_event_loop_op(EventLoopOp::SetImeAllowed {
868                window: self.inner.clone(),
869                allowed,
870                waker: tx,
871            })
872            .await;
873
874        rx.recv().await
875    }
876
877    /// Set the IME purpose.
878    pub async fn set_ime_purpose(&self, purpose: ImePurpose) {
879        let (tx, rx) = oneoff();
880        self.reactor
881            .push_event_loop_op(EventLoopOp::SetImePurpose {
882                window: self.inner.clone(),
883                purpose,
884                waker: tx,
885            })
886            .await;
887
888        rx.recv().await
889    }
890
891    /// Focus the window.
892    pub async fn focus_window(&self) {
893        let (tx, rx) = oneoff();
894        self.reactor
895            .push_event_loop_op(EventLoopOp::FocusWindow {
896                window: self.inner.clone(),
897                waker: tx,
898            })
899            .await;
900
901        rx.recv().await
902    }
903
904    /// Tell whether the window is focused.
905    pub async fn is_focused(&self) -> bool {
906        let (tx, rx) = oneoff();
907        self.reactor
908            .push_event_loop_op(EventLoopOp::Focused {
909                window: self.inner.clone(),
910                waker: tx,
911            })
912            .await;
913
914        rx.recv().await
915    }
916
917    /// Request the user's attention.
918    pub async fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
919        let (tx, rx) = oneoff();
920        self.reactor
921            .push_event_loop_op(EventLoopOp::RequestUserAttention {
922                window: self.inner.clone(),
923                request_type,
924                waker: tx,
925            })
926            .await;
927
928        rx.recv().await
929    }
930
931    /// Set the window's theme.
932    pub async fn set_theme(&self, theme: Option<Theme>) {
933        let (tx, rx) = oneoff();
934        self.reactor
935            .push_event_loop_op(EventLoopOp::SetTheme {
936                window: self.inner.clone(),
937                theme,
938                waker: tx,
939            })
940            .await;
941
942        rx.recv().await
943    }
944
945    /// Get the window's theme.
946    pub async fn theme(&self) -> Option<Theme> {
947        let (tx, rx) = oneoff();
948        self.reactor
949            .push_event_loop_op(EventLoopOp::Theme {
950                window: self.inner.clone(),
951                waker: tx,
952            })
953            .await;
954
955        rx.recv().await
956    }
957
958    /// Set the window's protected content.
959    pub async fn set_content_protected(&self, protected: bool) {
960        let (tx, rx) = oneoff();
961        self.reactor
962            .push_event_loop_op(EventLoopOp::SetProtectedContent {
963                window: self.inner.clone(),
964                protected,
965                waker: tx,
966            })
967            .await;
968
969        rx.recv().await
970    }
971
972    /// Get the title of the window.
973    pub async fn title(&self) -> String {
974        let (tx, rx) = oneoff();
975        self.reactor
976            .push_event_loop_op(EventLoopOp::Title {
977                window: self.inner.clone(),
978                waker: tx,
979            })
980            .await;
981
982        rx.recv().await
983    }
984
985    /// Set the cursor icon.
986    pub async fn set_cursor_icon(&self, icon: CursorIcon) {
987        let (tx, rx) = oneoff();
988        self.reactor
989            .push_event_loop_op(EventLoopOp::SetCursorIcon {
990                window: self.inner.clone(),
991                icon,
992                waker: tx,
993            })
994            .await;
995
996        rx.recv().await
997    }
998
999    /// Set the cursor position.
1000    pub async fn set_cursor_position(
1001        &self,
1002        posn: impl Into<Position>,
1003    ) -> Result<(), ExternalError> {
1004        let (tx, rx) = oneoff();
1005        self.reactor
1006            .push_event_loop_op(EventLoopOp::SetCursorPosition {
1007                window: self.inner.clone(),
1008                position: posn.into(),
1009                waker: tx,
1010            })
1011            .await;
1012
1013        rx.recv().await
1014    }
1015
1016    /// Set the cursor's grab mode.
1017    pub async fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> {
1018        let (tx, rx) = oneoff();
1019        self.reactor
1020            .push_event_loop_op(EventLoopOp::SetCursorGrab {
1021                window: self.inner.clone(),
1022                mode,
1023                waker: tx,
1024            })
1025            .await;
1026
1027        rx.recv().await
1028    }
1029
1030    /// Set the cursor's visibility.
1031    pub async fn set_cursor_visible(&self, visible: bool) {
1032        let (tx, rx) = oneoff();
1033        self.reactor
1034            .push_event_loop_op(EventLoopOp::SetCursorVisible {
1035                window: self.inner.clone(),
1036                visible,
1037                waker: tx,
1038            })
1039            .await;
1040
1041        rx.recv().await
1042    }
1043
1044    /// Drag the window.
1045    pub async fn drag_window(&self) -> Result<(), ExternalError> {
1046        let (tx, rx) = oneoff();
1047        self.reactor
1048            .push_event_loop_op(EventLoopOp::DragWindow {
1049                window: self.inner.clone(),
1050                waker: tx,
1051            })
1052            .await;
1053
1054        rx.recv().await
1055    }
1056
1057    /// Drag-resize the window.
1058    pub async fn drag_resize_window(
1059        &self,
1060        direction: ResizeDirection,
1061    ) -> Result<(), ExternalError> {
1062        let (tx, rx) = oneoff();
1063        self.reactor
1064            .push_event_loop_op(EventLoopOp::DragResizeWindow {
1065                window: self.inner.clone(),
1066                direction,
1067                waker: tx,
1068            })
1069            .await;
1070
1071        rx.recv().await
1072    }
1073
1074    /// Set the cursor hit test.
1075    pub async fn set_cursor_hittest(&self, hit_test: bool) -> Result<(), ExternalError> {
1076        let (tx, rx) = oneoff();
1077        self.reactor
1078            .push_event_loop_op(EventLoopOp::SetCursorHitTest {
1079                window: self.inner.clone(),
1080                hit_test,
1081                waker: tx,
1082            })
1083            .await;
1084
1085        rx.recv().await
1086    }
1087
1088    /// Get the current monitor of this window.
1089    pub async fn current_monitor(&self) -> Option<MonitorHandle> {
1090        let (tx, rx) = oneoff();
1091        self.reactor
1092            .push_event_loop_op(EventLoopOp::CurrentMonitor {
1093                window: self.inner.clone(),
1094                waker: tx,
1095            })
1096            .await;
1097
1098        rx.recv().await
1099    }
1100}
1101
1102/// Waiting for events.
1103impl<TS: ThreadSafety> Window<TS> {
1104    /// Get the handler for the `RedrawRequested` event.
1105    pub fn redraw_requested(&self) -> &Handler<(), TS> {
1106        &self.registration.redraw_requested
1107    }
1108
1109    /// Get the handler for the `CloseRequested` event.
1110    pub fn close_requested(&self) -> &Handler<(), TS> {
1111        &self.registration.close_requested
1112    }
1113
1114    /// Get the handler for the `Resized` event.
1115    pub fn resized(&self) -> &Handler<PhysicalSize<u32>, TS> {
1116        &self.registration.resized
1117    }
1118
1119    /// Get the handler for the `Moved` event.
1120    pub fn moved(&self) -> &Handler<PhysicalPosition<i32>, TS> {
1121        &self.registration.moved
1122    }
1123
1124    /// Get handler for the `Destroyed` event.
1125    pub fn destroyed(&self) -> &Handler<(), TS> {
1126        &self.registration.destroyed
1127    }
1128
1129    /// Get the handler for the `Focused` event.
1130    pub fn focused(&self) -> &Handler<bool, TS> {
1131        &self.registration.focused
1132    }
1133
1134    /// Get the handler for the `KeyboardInput` event.
1135    pub fn keyboard_input(&self) -> &Handler<crate::event::KeyboardInput, TS> {
1136        &self.registration.keyboard_input
1137    }
1138
1139    /// Get the handler for the `ModifiersChanged` event.
1140    pub fn modifiers_changed(&self) -> &Handler<crate::event::ModifiersState, TS> {
1141        &self.registration.modifiers_changed
1142    }
1143
1144    /// Get the handler for the `ReceivedCharacter` event.
1145    pub fn received_character(&self) -> &Handler<char, TS> {
1146        &self.registration.received_character
1147    }
1148
1149    /// Get the handler for the `Ime` event.
1150    pub fn ime(&self) -> &Handler<crate::event::Ime, TS> {
1151        &self.registration.ime
1152    }
1153
1154    /// Get the handler for the `CursorMoved` event.
1155    pub fn cursor_moved(&self) -> &Handler<crate::event::CursorMoved, TS> {
1156        &self.registration.cursor_moved
1157    }
1158
1159    /// Get the handler for the `CursorEntered` event.
1160    pub fn cursor_entered(&self) -> &Handler<DeviceId, TS> {
1161        &self.registration.cursor_entered
1162    }
1163
1164    /// Get the handler for the `CursorLeft` event.
1165    pub fn cursor_left(&self) -> &Handler<DeviceId, TS> {
1166        &self.registration.cursor_left
1167    }
1168
1169    /// Get the handle for the `MouseWheel` event.
1170    pub fn mouse_wheel(&self) -> &Handler<crate::event::MouseWheel, TS> {
1171        &self.registration.mouse_wheel
1172    }
1173
1174    /// Get the handle for the `MouseInput` event.
1175    pub fn mouse_input(&self) -> &Handler<crate::event::MouseInput, TS> {
1176        &self.registration.mouse_input
1177    }
1178
1179    /// Get the handle for the `TouchpadMagnify` event.
1180    pub fn touchpad_magnify(&self) -> &Handler<crate::event::TouchpadMagnify, TS> {
1181        &self.registration.touchpad_magnify
1182    }
1183
1184    /// Get the handle for the `TouchpadPressure` event.
1185    pub fn touchpad_pressure(&self) -> &Handler<crate::event::TouchpadPressure, TS> {
1186        &self.registration.touchpad_pressure
1187    }
1188
1189    /// Get the handle for the `Touch` event.
1190    pub fn touch(&self) -> &Handler<crate::event::Touch, TS> {
1191        &self.registration.touch
1192    }
1193
1194    /// Get the handle for the `ScaleFactorChanged` event.
1195    pub fn scale_factor_changed(&self) -> &Handler<crate::event::ScaleFactor, TS> {
1196        &self.registration.scale_factor_changed
1197    }
1198
1199    /// Get the handle for the `TouchpadRotate` event.
1200    pub fn touchpad_rotate(&self) -> &Handler<crate::event::TouchpadRotate, TS> {
1201        &self.registration.touchpad_rotate
1202    }
1203
1204    /// Get the handle for the `SmartMagnify` event.
1205    pub fn smart_magnify(&self) -> &Handler<DeviceId, TS> {
1206        &self.registration.smart_magnify
1207    }
1208
1209    /// Get the handle for the `AxisMotion` event.
1210    pub fn axis_motion(&self) -> &Handler<crate::event::AxisMotion, TS> {
1211        &self.registration.axis_motion
1212    }
1213
1214    /// Get the handle for the `ThemeChanged` event.
1215    pub fn theme_changed(&self) -> &Handler<Theme, TS> {
1216        &self.registration.theme_changed
1217    }
1218
1219    /// Get the handle for the `Occulded` event.
1220    pub fn occluded(&self) -> &Handler<bool, TS> {
1221        &self.registration.occluded
1222    }
1223}