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