use blitz_traits::navigation::NavigationOptions;
use futures_util::task::ArcWake;
use std::{any::Any, sync::Arc};
use winit::{event_loop::EventLoopProxy, window::WindowId};
#[cfg(feature = "accessibility")]
use accesskit_winit::{Event as AccessKitEvent, WindowEvent as AccessKitWindowEvent};
use blitz_dom::net::Resource;
#[derive(Debug, Clone)]
pub enum BlitzShellEvent {
Poll {
window_id: WindowId,
},
ResourceLoad {
doc_id: usize,
data: Resource,
},
#[cfg(feature = "accessibility")]
Accessibility {
window_id: WindowId,
data: Arc<AccessKitWindowEvent>,
},
Embedder(Arc<dyn Any + Send + Sync>),
Navigate(Box<NavigationOptions>),
NavigationLoad {
url: String,
contents: String,
retain_scroll_position: bool,
is_md: bool,
},
}
impl BlitzShellEvent {
pub fn embedder_event<T: Any + Send + Sync>(value: T) -> Self {
let boxed = Arc::new(value) as Arc<dyn Any + Send + Sync>;
Self::Embedder(boxed)
}
}
impl From<(usize, Resource)> for BlitzShellEvent {
fn from((doc_id, data): (usize, Resource)) -> Self {
BlitzShellEvent::ResourceLoad { doc_id, data }
}
}
#[cfg(feature = "accessibility")]
impl From<AccessKitEvent> for BlitzShellEvent {
fn from(value: AccessKitEvent) -> Self {
Self::Accessibility {
window_id: value.window_id,
data: Arc::new(value.window_event),
}
}
}
pub fn create_waker(proxy: &EventLoopProxy<BlitzShellEvent>, id: WindowId) -> std::task::Waker {
struct DomHandle {
proxy: EventLoopProxy<BlitzShellEvent>,
id: WindowId,
}
unsafe impl Send for DomHandle {}
unsafe impl Sync for DomHandle {}
impl ArcWake for DomHandle {
fn wake_by_ref(arc_self: &Arc<Self>) {
_ = arc_self.proxy.send_event(BlitzShellEvent::Poll {
window_id: arc_self.id,
})
}
}
futures_util::task::waker(Arc::new(DomHandle {
id,
proxy: proxy.clone(),
}))
}