eframe/native/
winit_integration.rs1use std::{sync::Arc, time::Instant};
2
3use winit::{
4 event_loop::ActiveEventLoop,
5 window::{Window, WindowId},
6};
7
8use egui::ViewportId;
9#[cfg(feature = "accesskit")]
10use egui_winit::accesskit_winit;
11
12pub fn create_egui_context(storage: Option<&dyn crate::Storage>) -> egui::Context {
14 profiling::function_scope!();
15
16 pub const IS_DESKTOP: bool = cfg!(any(
17 target_os = "freebsd",
18 target_os = "linux",
19 target_os = "macos",
20 target_os = "openbsd",
21 target_os = "windows",
22 ));
23
24 let egui_ctx = egui::Context::default();
25
26 egui_ctx.set_embed_viewports(!IS_DESKTOP);
27
28 egui_ctx.options_mut(|o| {
29 o.max_passes = 2.try_into().unwrap();
31 });
32
33 let memory = crate::native::epi_integration::load_egui_memory(storage).unwrap_or_default();
34 egui_ctx.memory_mut(|mem| *mem = memory);
35
36 egui_ctx
37}
38
39#[derive(Debug)]
41pub enum UserEvent {
42 RequestRepaint {
44 viewport_id: ViewportId,
46
47 when: Instant,
49
50 cumulative_pass_nr: u64,
52 },
53
54 #[cfg(feature = "accesskit")]
56 AccessKitActionRequest(accesskit_winit::Event),
57}
58
59#[cfg(feature = "accesskit")]
60impl From<accesskit_winit::Event> for UserEvent {
61 fn from(inner: accesskit_winit::Event) -> Self {
62 Self::AccessKitActionRequest(inner)
63 }
64}
65
66pub trait WinitApp {
67 fn egui_ctx(&self) -> Option<&egui::Context>;
68
69 fn window(&self, window_id: WindowId) -> Option<Arc<Window>>;
70
71 fn window_id_from_viewport_id(&self, id: ViewportId) -> Option<WindowId>;
72
73 fn save_and_destroy(&mut self);
74
75 fn run_ui_and_paint(
76 &mut self,
77 event_loop: &ActiveEventLoop,
78 window_id: WindowId,
79 ) -> crate::Result<EventResult>;
80
81 fn suspended(&mut self, event_loop: &ActiveEventLoop) -> crate::Result<EventResult>;
82
83 fn resumed(&mut self, event_loop: &ActiveEventLoop) -> crate::Result<EventResult>;
84
85 fn device_event(
86 &mut self,
87 event_loop: &ActiveEventLoop,
88 device_id: winit::event::DeviceId,
89 event: winit::event::DeviceEvent,
90 ) -> crate::Result<EventResult>;
91
92 fn window_event(
93 &mut self,
94 event_loop: &ActiveEventLoop,
95 window_id: WindowId,
96 event: winit::event::WindowEvent,
97 ) -> crate::Result<EventResult>;
98
99 #[cfg(feature = "accesskit")]
100 fn on_accesskit_event(&mut self, event: accesskit_winit::Event) -> crate::Result<EventResult>;
101}
102
103#[derive(Clone, Copy, Debug, PartialEq, Eq)]
104pub enum EventResult {
105 Wait,
106
107 RepaintNow(WindowId),
114
115 RepaintNext(WindowId),
119
120 RepaintAt(WindowId, Instant),
121
122 Exit,
123}
124
125#[cfg(feature = "accesskit")]
126pub(crate) fn on_accesskit_window_event(
127 egui_winit: &mut egui_winit::State,
128 window_id: WindowId,
129 event: &accesskit_winit::WindowEvent,
130) -> EventResult {
131 match event {
132 accesskit_winit::WindowEvent::InitialTreeRequested => {
133 egui_winit.egui_ctx().enable_accesskit();
134 EventResult::RepaintNow(window_id)
142 }
143 accesskit_winit::WindowEvent::ActionRequested(request) => {
144 egui_winit.on_accesskit_action_request(request.clone());
145 EventResult::RepaintNext(window_id)
148 }
149 accesskit_winit::WindowEvent::AccessibilityDeactivated => {
150 egui_winit.egui_ctx().disable_accesskit();
151 EventResult::Wait
154 }
155 }
156}