1use futures_util::task::ArcWake;
2use std::{any::Any, sync::Arc};
3use winit::{event_loop::EventLoopProxy, window::WindowId};
4
5#[cfg(feature = "accessibility")]
6use accesskit_winit::{Event as AccessKitEvent, WindowEvent as AccessKitWindowEvent};
7use blitz_dom::net::Resource;
8
9#[derive(Debug, Clone)]
10pub enum BlitzShellEvent {
11 Poll {
12 window_id: WindowId,
13 },
14
15 ResourceLoad {
16 doc_id: usize,
17 data: Resource,
18 },
19
20 #[cfg(feature = "accessibility")]
22 Accessibility {
23 window_id: WindowId,
24 data: Arc<AccessKitWindowEvent>,
25 },
26
27 Embedder(Arc<dyn Any + Send + Sync>),
29
30 Navigate(String),
32}
33impl BlitzShellEvent {
34 pub fn embedder_event<T: Any + Send + Sync>(value: T) -> Self {
35 let boxed = Arc::new(value) as Arc<dyn Any + Send + Sync>;
36 Self::Embedder(boxed)
37 }
38}
39impl From<(usize, Resource)> for BlitzShellEvent {
40 fn from((doc_id, data): (usize, Resource)) -> Self {
41 BlitzShellEvent::ResourceLoad { doc_id, data }
42 }
43}
44
45#[cfg(feature = "accessibility")]
46impl From<AccessKitEvent> for BlitzShellEvent {
47 fn from(value: AccessKitEvent) -> Self {
48 Self::Accessibility {
49 window_id: value.window_id,
50 data: Arc::new(value.window_event),
51 }
52 }
53}
54
55pub fn create_waker(proxy: &EventLoopProxy<BlitzShellEvent>, id: WindowId) -> std::task::Waker {
61 struct DomHandle {
62 proxy: EventLoopProxy<BlitzShellEvent>,
63 id: WindowId,
64 }
65
66 unsafe impl Send for DomHandle {}
69 unsafe impl Sync for DomHandle {}
70
71 impl ArcWake for DomHandle {
72 fn wake_by_ref(arc_self: &Arc<Self>) {
73 _ = arc_self.proxy.send_event(BlitzShellEvent::Poll {
74 window_id: arc_self.id,
75 })
76 }
77 }
78
79 futures_util::task::waker(Arc::new(DomHandle {
80 id,
81 proxy: proxy.clone(),
82 }))
83}