diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 825852285..82ed5c647 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -224,154 +224,154 @@ fn run_and_return( returned_result } -fn run_and_exit(event_loop: EventLoop, mut winit_app: impl WinitApp + 'static) -> ! { +fn run_and_exit( + event_loop: EventLoop, + mut winit_app: impl WinitApp + 'static, +) -> Result<()> { use winit::event_loop::ControlFlow; log::debug!("Entering the winit event loop (run)…"); // When to repaint what window let mut windows_next_repaint_times = HashMap::default(); - let result = event_loop.run(move |event, event_loop_window_target| { - crate::profile_scope!("winit_event", short_event_description(&event)); + event_loop + .run(move |event, event_loop_window_target| { + crate::profile_scope!("winit_event", short_event_description(&event)); - let event_result = match &event { - winit::event::Event::LoopExiting => { - log::debug!("Received Event::LoopExiting"); - EventResult::Exit - } + let event_result = match &event { + winit::event::Event::LoopExiting => { + log::debug!("Received Event::LoopExiting"); + EventResult::Exit + } - winit::event::Event::WindowEvent { - event: winit::event::WindowEvent::RedrawRequested, - window_id, - } => { - windows_next_repaint_times.remove(window_id); - winit_app.run_ui_and_paint(*window_id) - } + winit::event::Event::WindowEvent { + event: winit::event::WindowEvent::RedrawRequested, + window_id, + } => { + windows_next_repaint_times.remove(window_id); + winit_app.run_ui_and_paint(*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 { - if let Some(window_id) = winit_app.window_id_from_viewport_id(*viewport_id) { - EventResult::RepaintAt(window_id, *when) + 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 { + if let Some(window_id) = winit_app.window_id_from_viewport_id(*viewport_id) + { + EventResult::RepaintAt(window_id, *when) + } else { + EventResult::Wait + } } else { - EventResult::Wait + log::trace!("Got outdated UserEvent::RequestRepaint"); + EventResult::Wait // old request - we've already repainted } - } 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) => event_result, - Err(err) => { - panic!("eframe encountered a fatal error: {err} during event {event:?}"); + winit::event::Event::NewEvents(winit::event::StartCause::ResumeTimeReached { + .. + }) => { + log::trace!("Woke up to check next_repaint_time"); + EventResult::Wait } - }, - }; - match event_result { - EventResult::Wait => { - event_loop_window_target.set_control_flow(ControlFlow::Wait); - } - EventResult::RepaintNow(window_id) => { - log::trace!("Repaint 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); + event => match winit_app.on_event(event_loop_window_target, event) { + Ok(event_result) => event_result, + Err(err) => { + panic!("eframe encountered a fatal error: {err} during event {event:?}"); + } + }, + }; - winit_app.run_ui_and_paint(window_id); - } else { - // Fix for https://github.com/emilk/egui/issues/2425 + match event_result { + EventResult::Wait => { + event_loop_window_target.set_control_flow(ControlFlow::Wait); + } + EventResult::RepaintNow(window_id) => { + log::trace!("Repaint 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(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!("Repaint caused by {}", short_event_description(&event)); windows_next_repaint_times.insert(window_id, Instant::now()); } - } - EventResult::RepaintNext(window_id) => { - log::trace!("Repaint 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!("Quitting - saving app state…"); - winit_app.save_and_destroy(); - #[allow(clippy::exit)] - std::process::exit(0); - } - } - - let mut next_repaint_time = windows_next_repaint_times.values().min().copied(); - - // This is for not duplicating redraw requests - use winit::event::Event; - if matches!( - event, - Event::WindowEvent { - event: winit::event::WindowEvent::RedrawRequested, - .. - } | Event::Resumed - ) { - windows_next_repaint_times.retain(|window_id, repaint_time| { - if Instant::now() < *repaint_time { - return true; + 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)), + ); } - - 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:?}"); - window.request_redraw(); - true - } else { - false + EventResult::Exit => { + log::debug!("Quitting - saving app state…"); + winit_app.save_and_destroy(); + #[allow(clippy::exit)] + std::process::exit(0); } - }); - } - - if let Some(next_repaint_time) = next_repaint_time { - let time_until_next = next_repaint_time.saturating_duration_since(Instant::now()); - if time_until_next < std::time::Duration::from_secs(10_000) { - log::trace!("WaitUntil {time_until_next:?}"); } - // WaitUntil seems to not work on iOS - #[cfg(target_os = "ios")] - winit_app - .get_window_winit_id(ViewportId::ROOT) - .map(|window_id| { - winit_app - .window(window_id) - .map(|window| window.request_redraw()) + let mut next_repaint_time = windows_next_repaint_times.values().min().copied(); + + // This is for not duplicating redraw requests + use winit::event::Event; + if matches!( + event, + Event::WindowEvent { + event: winit::event::WindowEvent::RedrawRequested, + .. + } | Event::Resumed + ) { + windows_next_repaint_times.retain(|window_id, repaint_time| { + if Instant::now() < *repaint_time { + return true; + } + + 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:?}"); + window.request_redraw(); + true + } else { + false + } }); + } - event_loop_window_target.set_control_flow(ControlFlow::WaitUntil(next_repaint_time)); - }; - }); + if let Some(next_repaint_time) = next_repaint_time { + let time_until_next = next_repaint_time.saturating_duration_since(Instant::now()); + if time_until_next < std::time::Duration::from_secs(10_000) { + log::trace!("WaitUntil {time_until_next:?}"); + } - std::process::exit(if let Err(e) = result { - log::warn!("Error from event loop: {e}"); - 1 - } else { - 0 - }); + // WaitUntil seems to not work on iOS + #[cfg(target_os = "ios")] + winit_app + .get_window_winit_id(ViewportId::ROOT) + .map(|window_id| { + winit_app + .window(window_id) + .map(|window| window.request_redraw()) + }); + + event_loop_window_target + .set_control_flow(ControlFlow::WaitUntil(next_repaint_time)); + }; + }) + .map_err(|e| e.into()) } // ---------------------------------------------------------------------------- @@ -394,7 +394,7 @@ pub fn run_glow( let event_loop = create_event_loop(&mut native_options); let glow_eframe = GlowWinitApp::new(&event_loop, app_name, native_options, app_creator); - run_and_exit(event_loop, glow_eframe); + run_and_exit(event_loop, glow_eframe) } // ---------------------------------------------------------------------------- @@ -417,5 +417,5 @@ pub fn run_wgpu( let event_loop = create_event_loop(&mut native_options); let wgpu_eframe = WgpuWinitApp::new(&event_loop, app_name, native_options, app_creator); - run_and_exit(event_loop, wgpu_eframe); + run_and_exit(event_loop, wgpu_eframe) }