eframe/native/
winit_integration.rsuse std::{sync::Arc, time::Instant};
use winit::{
event_loop::ActiveEventLoop,
window::{Window, WindowId},
};
use egui::ViewportId;
#[cfg(feature = "accesskit")]
use egui_winit::accesskit_winit;
pub fn create_egui_context(storage: Option<&dyn crate::Storage>) -> egui::Context {
profiling::function_scope!();
pub const IS_DESKTOP: bool = cfg!(any(
target_os = "freebsd",
target_os = "linux",
target_os = "macos",
target_os = "openbsd",
target_os = "windows",
));
let egui_ctx = egui::Context::default();
egui_ctx.set_embed_viewports(!IS_DESKTOP);
egui_ctx.options_mut(|o| {
o.max_passes = 2.try_into().unwrap();
});
let memory = crate::native::epi_integration::load_egui_memory(storage).unwrap_or_default();
egui_ctx.memory_mut(|mem| *mem = memory);
egui_ctx
}
#[derive(Debug)]
pub enum UserEvent {
RequestRepaint {
viewport_id: ViewportId,
when: Instant,
cumulative_pass_nr: u64,
},
#[cfg(feature = "accesskit")]
AccessKitActionRequest(accesskit_winit::Event),
}
#[cfg(feature = "accesskit")]
impl From<accesskit_winit::Event> for UserEvent {
fn from(inner: accesskit_winit::Event) -> Self {
Self::AccessKitActionRequest(inner)
}
}
pub trait WinitApp {
fn egui_ctx(&self) -> Option<&egui::Context>;
fn window(&self, window_id: WindowId) -> Option<Arc<Window>>;
fn window_id_from_viewport_id(&self, id: ViewportId) -> Option<WindowId>;
fn save_and_destroy(&mut self);
fn run_ui_and_paint(
&mut self,
event_loop: &ActiveEventLoop,
window_id: WindowId,
) -> crate::Result<EventResult>;
fn suspended(&mut self, event_loop: &ActiveEventLoop) -> crate::Result<EventResult>;
fn resumed(&mut self, event_loop: &ActiveEventLoop) -> crate::Result<EventResult>;
fn device_event(
&mut self,
event_loop: &ActiveEventLoop,
device_id: winit::event::DeviceId,
event: winit::event::DeviceEvent,
) -> crate::Result<EventResult>;
fn window_event(
&mut self,
event_loop: &ActiveEventLoop,
window_id: WindowId,
event: winit::event::WindowEvent,
) -> crate::Result<EventResult>;
#[cfg(feature = "accesskit")]
fn on_accesskit_event(&mut self, event: accesskit_winit::Event) -> crate::Result<EventResult>;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum EventResult {
Wait,
RepaintNow(WindowId),
RepaintNext(WindowId),
RepaintAt(WindowId, Instant),
Exit,
}
#[cfg(feature = "accesskit")]
pub(crate) fn on_accesskit_window_event(
egui_winit: &mut egui_winit::State,
window_id: WindowId,
event: &accesskit_winit::WindowEvent,
) -> EventResult {
match event {
accesskit_winit::WindowEvent::InitialTreeRequested => {
egui_winit.egui_ctx().enable_accesskit();
EventResult::RepaintNow(window_id)
}
accesskit_winit::WindowEvent::ActionRequested(request) => {
egui_winit.on_accesskit_action_request(request.clone());
EventResult::RepaintNext(window_id)
}
accesskit_winit::WindowEvent::AccessibilityDeactivated => {
egui_winit.egui_ctx().disable_accesskit();
EventResult::Wait
}
}
}