Skip to main content

winit_async/
window.rs

1use crate::tls::{runtime, try_runtime};
2use async_local_channel::spsc;
3use std::pin::{Pin, pin};
4use std::task::{Context, Poll};
5use winit::event::WindowEvent;
6use winit::window::{Window, WindowId};
7
8pub struct WindowEvents {
9    window_id: WindowId,
10    rx: spsc::Receiver<WindowEvent>,
11}
12
13impl WindowEvents {
14    #[inline]
15    pub const fn next_event(&mut self) -> WindowEventFuture<'_> {
16        WindowEventFuture { inner: self }
17    }
18}
19
20pub struct WindowEventFuture<'a> {
21    inner: &'a WindowEvents,
22}
23
24impl Future for WindowEventFuture<'_> {
25    type Output = Option<WindowEvent>;
26
27    #[inline]
28    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
29        pin!(self.inner.rx.recv()).poll(cx).map(Result::ok)
30    }
31}
32
33impl Drop for WindowEvents {
34    #[inline]
35    fn drop(&mut self) {
36        if let Some(mut runtime) = try_runtime() {
37            runtime.window_event_receiver_dropped(self.window_id);
38        }
39    }
40}
41
42pub trait WindowExtAsync {
43    fn events(&self) -> Option<WindowEvents>;
44}
45
46impl WindowExtAsync for Window {
47    #[inline]
48    fn events(&self) -> Option<WindowEvents> {
49        let window_id = self.id();
50        let rx = runtime().window_event_receiver(window_id)?;
51        Some(WindowEvents { window_id, rx })
52    }
53}