Skip to content

Commit

Permalink
Small touch-ups of the event loop
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Nov 14, 2023
1 parent 17614cd commit d6c1505
Showing 1 changed file with 38 additions and 46 deletions.
84 changes: 38 additions & 46 deletions crates/eframe/src/native/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ fn run_and_return(

log::debug!("Entering the winit event loop (run_return)…");

// When to repaint what window
let mut windows_next_repaint_times = HashMap::default();

let mut returned_result = Ok(());
Expand Down Expand Up @@ -209,18 +210,10 @@ fn run_and_return(
EventResult::Wait
}

winit::event::Event::WindowEvent { window_id, .. }
if winit_app.window(*window_id).is_none() =>
{
// This can happen if we close a window, and then reopen a new one,
// or if we have multiple windows open.
EventResult::RepaintNext(*window_id)
}

event => match winit_app.on_event(event_loop, event) {
Ok(event_result) => event_result,
Err(err) => {
log::error!("Exiting because of error: {err} on event {event:?}");
log::error!("Exiting because of error: {err} during event {event:?}");
returned_result = Err(err);
EventResult::Exit
}
Expand All @@ -232,7 +225,7 @@ fn run_and_return(
control_flow.set_wait();
}
EventResult::RepaintNow(window_id) => {
log::trace!("Repaint caused by winit::Event: {:?}", event_result);
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);
Expand All @@ -244,7 +237,7 @@ fn run_and_return(
}
}
EventResult::RepaintNext(window_id) => {
log::trace!("Repaint caused by winit::Event: {:?}", event_result);
log::trace!("Repaint caused by {}", short_event_description(&event));
windows_next_repaint_times.insert(window_id, Instant::now());
}
EventResult::RepaintAt(window_id, repaint_time) => {
Expand Down Expand Up @@ -282,7 +275,6 @@ fn run_and_return(
if let Some(window) = winit_app.window(*window_id) {
log::trace!("request_redraw for {window_id:?}");
window.request_redraw();

true
} else {
false
Expand Down Expand Up @@ -321,6 +313,7 @@ fn run_and_return(
fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp + 'static) -> ! {
log::debug!("Entering the winit event loop (run)…");

// When to repaint what window
let mut windows_next_repaint_times = HashMap::default();

event_loop.run(move |event, event_loop, control_flow| {
Expand Down Expand Up @@ -350,25 +343,32 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
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 {
..
}) => EventResult::Wait, // We just woke up to check next_repaint_time
}) => {
log::trace!("Woke up to check next_repaint_time");
EventResult::Wait
}

event => match winit_app.on_event(event_loop, event) {
Ok(event_result) => event_result,
Err(err) => {
panic!("eframe encountered a fatal error: {err}");
panic!("eframe encountered a fatal error: {err} during event {event:?}");
}
},
};

match event_result {
EventResult::Wait => {}
EventResult::Wait => {
control_flow.set_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);
Expand All @@ -380,6 +380,7 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
}
}
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) => {
Expand Down Expand Up @@ -417,7 +418,6 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
if let Some(window) = winit_app.window(*window_id) {
log::trace!("request_redraw for {window_id:?}");
window.request_redraw();

true
} else {
false
Expand Down Expand Up @@ -673,6 +673,13 @@ mod glow_integration {
event: &winit::event::WindowEvent<'_>,
focused_viewport: &mut Option<ViewportId>,
) -> EventResult {
let viewport_id = self
.glutin
.borrow()
.viewport_from_window
.get(&window_id)
.copied();

// On Windows, if a window is resized by the user, it should repaint synchronously, inside the
// event handler.
//
Expand All @@ -688,48 +695,34 @@ mod glow_integration {
// See: https://github.com/emilk/egui/issues/903
let mut repaint_asap = false;

match &event {
match event {
winit::event::WindowEvent::Focused(new_focused) => {
*focused_viewport = new_focused
.then(|| {
self.glutin
.borrow_mut()
.viewport_from_window
.get(&window_id)
.copied()
})
.flatten();
*focused_viewport = new_focused.then(|| viewport_id).flatten();
}

winit::event::WindowEvent::Resized(physical_size) => {
repaint_asap = true;

// Resize with 0 width and height is used by winit to signal a minimize event on Windows.
// See: https://github.com/rust-windowing/winit/issues/208
// This solves an issue where the app would panic when minimizing on Windows.
let glutin = &mut *self.glutin.borrow_mut();
if 0 < physical_size.width && 0 < physical_size.height {
if let Some(id) = glutin.viewport_from_window.get(&window_id) {
glutin.resize(*id, *physical_size);
if let Some(viewport_id) = viewport_id {
repaint_asap = true;
self.glutin.borrow_mut().resize(viewport_id, *physical_size);
}
}
}

winit::event::WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
let glutin = &mut *self.glutin.borrow_mut();
repaint_asap = true;
if let Some(id) = glutin.viewport_from_window.get(&window_id) {
glutin.resize(*id, **new_inner_size);
if let Some(viewport_id) = viewport_id {
repaint_asap = true;
self.glutin
.borrow_mut()
.resize(viewport_id, **new_inner_size);
}
}

winit::event::WindowEvent::CloseRequested => {
let is_root = self
.glutin
.borrow()
.viewport_from_window
.get(&window_id)
.map_or(false, |id| *id == ViewportId::ROOT);
let is_root = viewport_id == Some(ViewportId::ROOT);
if is_root && self.integration.should_close() {
log::debug!("Received WindowEvent::CloseRequested");
return EventResult::Exit;
Expand All @@ -739,8 +732,8 @@ mod glow_integration {
}

let event_response = 'res: {
let mut glutin = self.glutin.borrow_mut();
if let Some(viewport_id) = glutin.viewport_from_window.get(&window_id).copied() {
if let Some(viewport_id) = viewport_id {
let mut glutin = self.glutin.borrow_mut();
if let Some(viewport) = glutin.viewports.get_mut(&viewport_id) {
break 'res self.integration.on_event(
self.app.as_mut(),
Expand Down Expand Up @@ -2618,13 +2611,11 @@ mod wgpu_integration {
// See: https://github.com/emilk/egui/issues/903
let mut repaint_asap = false;

match &event {
match event {
winit::event::WindowEvent::Focused(new_focused) => {
*focused_viewport = new_focused.then(|| viewport_id).flatten();
}
winit::event::WindowEvent::Resized(physical_size) => {
repaint_asap = true;

// Resize with 0 width and height is used by winit to signal a minimize event on Windows.
// See: https://github.com/rust-windowing/winit/issues/208
// This solves an issue where the app would panic when minimizing on Windows.
Expand All @@ -2634,6 +2625,7 @@ mod wgpu_integration {
NonZeroU32::new(physical_size.width),
NonZeroU32::new(physical_size.height),
) {
repaint_asap = true;
shared.painter.on_window_resized(viewport_id, width, height);
}
}
Expand Down

0 comments on commit d6c1505

Please sign in to comment.