-
Notifications
You must be signed in to change notification settings - Fork 2k
eframe: Switch to winit ApplicationManager api #4709
Copy link
Copy link
Closed
Labels
egui-winitporblems related to winitporblems related to winit
Description
The next version of winit will remove the run APIs: rust-windowing/winit#3683. This pretty extensively breaks code like
egui/crates/eframe/src/native/run.rs
Lines 73 to 208 in 93d458b
| event_loop.run_on_demand(|event, event_loop_window_target| { | |
| crate::profile_scope!("winit_event", short_event_description(&event)); | |
| log::trace!("winit event: {event:?}"); | |
| if matches!(event, winit::event::Event::AboutToWait) { | |
| return; // early-out: don't trigger another wait | |
| } | |
| let event_result = match &event { | |
| winit::event::Event::LoopExiting => { | |
| // On Mac, Cmd-Q we get here and then `run_on_demand` doesn't return (despite its name), | |
| // so we need to save state now: | |
| log::debug!("Received Event::LoopExiting - saving app state…"); | |
| winit_app.save_and_destroy(); | |
| return; | |
| } | |
| winit::event::Event::WindowEvent { | |
| event: winit::event::WindowEvent::RedrawRequested, | |
| window_id, | |
| } => { | |
| windows_next_repaint_times.remove(window_id); | |
| winit_app.run_ui_and_paint(event_loop_window_target, *window_id) | |
| } | |
| winit::event::Event::UserEvent(UserEvent::RequestRepaint { | |
| when, | |
| frame_nr, | |
| viewport_id, | |
| }) => { | |
| let current_frame_nr = winit_app.frame_nr(*viewport_id); | |
| if current_frame_nr == *frame_nr || current_frame_nr == *frame_nr + 1 { | |
| log::trace!("UserEvent::RequestRepaint scheduling repaint at {when:?}"); | |
| if let Some(window_id) = winit_app.window_id_from_viewport_id(*viewport_id) { | |
| EventResult::RepaintAt(window_id, *when) | |
| } else { | |
| EventResult::Wait | |
| } | |
| } else { | |
| log::trace!("Got outdated UserEvent::RequestRepaint"); | |
| EventResult::Wait // old request - we've already repainted | |
| } | |
| } | |
| winit::event::Event::NewEvents(winit::event::StartCause::ResumeTimeReached { | |
| .. | |
| }) => { | |
| log::trace!("Woke up to check next_repaint_time"); | |
| EventResult::Wait | |
| } | |
| event => match winit_app.on_event(event_loop_window_target, event) { | |
| Ok(event_result) => { | |
| log::trace!("event_result: {event_result:?}"); | |
| event_result | |
| } | |
| Err(err) => { | |
| log::error!("Exiting because of error: {err} during event {event:?}"); | |
| returned_result = Err(err); | |
| EventResult::Exit | |
| } | |
| }, | |
| }; | |
| match event_result { | |
| EventResult::Wait => { | |
| event_loop_window_target.set_control_flow(ControlFlow::Wait); | |
| } | |
| EventResult::RepaintNow(window_id) => { | |
| log::trace!( | |
| "RepaintNow of {window_id:?} caused by {}", | |
| short_event_description(&event) | |
| ); | |
| if cfg!(target_os = "windows") { | |
| // Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280 | |
| windows_next_repaint_times.remove(&window_id); | |
| winit_app.run_ui_and_paint(event_loop_window_target, window_id); | |
| } else { | |
| // Fix for https://github.com/emilk/egui/issues/2425 | |
| windows_next_repaint_times.insert(window_id, Instant::now()); | |
| } | |
| } | |
| EventResult::RepaintNext(window_id) => { | |
| log::trace!( | |
| "RepaintNext of {window_id:?} caused by {}", | |
| short_event_description(&event) | |
| ); | |
| windows_next_repaint_times.insert(window_id, Instant::now()); | |
| } | |
| EventResult::RepaintAt(window_id, repaint_time) => { | |
| windows_next_repaint_times.insert( | |
| window_id, | |
| windows_next_repaint_times | |
| .get(&window_id) | |
| .map_or(repaint_time, |last| (*last).min(repaint_time)), | |
| ); | |
| } | |
| EventResult::Exit => { | |
| log::debug!("Asking to exit event loop…"); | |
| winit_app.save_and_destroy(); | |
| event_loop_window_target.exit(); | |
| return; | |
| } | |
| } | |
| let mut next_repaint_time = windows_next_repaint_times.values().min().copied(); | |
| windows_next_repaint_times.retain(|window_id, repaint_time| { | |
| if Instant::now() < *repaint_time { | |
| return true; // not yet ready | |
| }; | |
| next_repaint_time = None; | |
| event_loop_window_target.set_control_flow(ControlFlow::Poll); | |
| if let Some(window) = winit_app.window(*window_id) { | |
| log::trace!("request_redraw for {window_id:?}"); | |
| let is_minimized = window.is_minimized().unwrap_or(false); | |
| if is_minimized { | |
| false | |
| } else { | |
| window.request_redraw(); | |
| true | |
| } | |
| } else { | |
| log::trace!("No window found for {window_id:?}"); | |
| false | |
| } | |
| }); | |
| if let Some(next_repaint_time) = next_repaint_time { | |
| event_loop_window_target.set_control_flow(ControlFlow::WaitUntil(next_repaint_time)); | |
| }; | |
| })?; |
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
egui-winitporblems related to winitporblems related to winit