1#![allow(clippy::missing_transmute_annotations)]
3
4mod device;
5mod error;
6mod map;
7mod runtime;
8mod tls;
9mod window;
10
11use crate::tls::runtime;
12use runtime::run;
13use std::future::pending;
14use winit::error::OsError;
15use winit::event_loop::{DeviceEvents, OwnedDisplayHandle};
16use winit::monitor::MonitorHandle;
17use winit::window::{CustomCursor, CustomCursorSource, Theme, Window, WindowAttributes};
18
19pub use crate::device::DeviceEventListener;
20pub use async_local_executor::{JoinHandle, TaskHandle, spawn_local};
21pub use error::Error;
22pub use window::{WindowEventFuture, WindowEvents, WindowExtAsync};
23pub use winit;
24
25#[inline]
26pub fn create_window(window_attributes: WindowAttributes) -> Result<Window, OsError> {
27 runtime().event_loop().create_window(window_attributes)
28}
29
30#[inline]
31pub fn create_custom_cursor(custom_cursor: CustomCursorSource) -> CustomCursor {
32 runtime().event_loop().create_custom_cursor(custom_cursor)
33}
34
35#[inline]
36pub fn available_monitors() -> Vec<MonitorHandle> {
37 runtime().event_loop().available_monitors().collect()
38}
39
40#[inline]
41pub fn primary_monitor() -> Option<MonitorHandle> {
42 runtime().event_loop().primary_monitor()
43}
44
45#[inline]
46pub fn listen_device_events(allowed: DeviceEvents) {
47 runtime().event_loop().listen_device_events(allowed)
48}
49
50#[inline]
51pub fn system_theme() -> Option<Theme> {
52 runtime().event_loop().system_theme()
53}
54
55#[inline]
56pub async fn exit() -> ! {
57 runtime().event_loop().exit();
58 pending::<()>().await;
59 unreachable!()
60}
61
62#[inline]
63pub fn owned_display_handle() -> OwnedDisplayHandle {
64 runtime().event_loop().owned_display_handle()
65}
66
67#[inline]
68pub async fn resumed() {
69 if let Some(rx) = { runtime().resumed_rx() } {
70 rx.recv().await.unwrap();
71 }
72}
73
74#[inline]
75pub async fn suspended() {
76 if let Some(rx) = { runtime().suspended_rx() } {
77 rx.recv().await.unwrap();
78 }
79}
80
81#[inline]
82pub fn device_events() -> Option<DeviceEventListener> {
83 DeviceEventListener::new()
84}
85
86#[inline]
87pub fn run_app<E, F>(future: F) -> Result<(), Error<E>>
88where
89 F: IntoFuture<Output = Result<(), E>> + 'static,
90{
91 let future = async move {
92 let result = future.await;
93 runtime().event_loop().exit();
94 result
95 };
96 let handle = run(future).map_err(Error::EventLoop)?;
97 let Some(result) = handle.result() else {
98 return Ok(());
99 };
100 result.map_err(Error::App)
101}