mirror of
https://github.com/emilk/egui.git
synced 2026-06-28 07:23:13 -04:00
Merge branch 'master' into feat-window-actions
This commit is contained in:
@@ -147,7 +147,7 @@ pub fn handle_app_output(
|
||||
fullscreen,
|
||||
drag_window,
|
||||
window_pos,
|
||||
visible,
|
||||
visible: _, // handled in post_present
|
||||
always_on_top,
|
||||
minimized,
|
||||
maximized,
|
||||
@@ -186,10 +186,6 @@ pub fn handle_app_output(
|
||||
let _ = window.drag_window();
|
||||
}
|
||||
|
||||
if let Some(visible) = visible {
|
||||
window.set_visible(visible);
|
||||
}
|
||||
|
||||
if let Some(always_on_top) = always_on_top {
|
||||
window.set_always_on_top(always_on_top);
|
||||
}
|
||||
@@ -251,7 +247,10 @@ impl EpiIntegration {
|
||||
native_pixels_per_point: Some(native_pixels_per_point),
|
||||
window_info: read_window_info(window, egui_ctx.pixels_per_point()),
|
||||
},
|
||||
output: Default::default(),
|
||||
output: epi::backend::AppOutput {
|
||||
visible: Some(true),
|
||||
..Default::default()
|
||||
},
|
||||
storage,
|
||||
#[cfg(feature = "glow")]
|
||||
gl,
|
||||
@@ -336,6 +335,7 @@ impl EpiIntegration {
|
||||
if app_output.close {
|
||||
self.close = app.on_close_event();
|
||||
}
|
||||
self.frame.output.visible = app_output.visible; // this is handled by post_present
|
||||
handle_app_output(window, self.egui_ctx.pixels_per_point(), app_output);
|
||||
}
|
||||
|
||||
@@ -352,6 +352,12 @@ impl EpiIntegration {
|
||||
app.post_rendering(window_size_px, &self.frame);
|
||||
}
|
||||
|
||||
pub fn post_present(&mut self, window: &winit::window::Window) {
|
||||
if let Some(visible) = self.frame.output.visible.take() {
|
||||
window.set_visible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_platform_output(
|
||||
&mut self,
|
||||
window: &winit::window::Window,
|
||||
|
||||
@@ -22,7 +22,17 @@ pub use epi::NativeOptions;
|
||||
#[derive(Debug)]
|
||||
enum EventResult {
|
||||
Wait,
|
||||
RepaintAsap,
|
||||
/// Causes a synchronous repaint inside the event handler. This should only
|
||||
/// be used in special situations if the window must be repainted while
|
||||
/// handling a specific event. This occurs on Windows when handling resizes.
|
||||
///
|
||||
/// `RepaintNow` creates a new frame synchronously, and should therefore
|
||||
/// only be used for extremely urgent repaints.
|
||||
RepaintNow,
|
||||
/// Queues a repaint for once the event loop handles its next redraw. Exists
|
||||
/// so that multiple input events can be handled in one frame. Does not
|
||||
/// cause any delay like `RepaintNow`.
|
||||
RepaintNext,
|
||||
RepaintAt(Instant),
|
||||
Exit,
|
||||
}
|
||||
@@ -103,7 +113,7 @@ fn run_and_return(event_loop: &mut EventLoop<RequestRepaintEvent>, mut winit_app
|
||||
winit::event::Event::UserEvent(RequestRepaintEvent)
|
||||
| winit::event::Event::NewEvents(winit::event::StartCause::ResumeTimeReached {
|
||||
..
|
||||
}) => EventResult::RepaintAsap,
|
||||
}) => EventResult::RepaintNext,
|
||||
|
||||
winit::event::Event::WindowEvent { window_id, .. }
|
||||
if winit_app.window().is_none()
|
||||
@@ -119,7 +129,12 @@ fn run_and_return(event_loop: &mut EventLoop<RequestRepaintEvent>, mut winit_app
|
||||
|
||||
match event_result {
|
||||
EventResult::Wait => {}
|
||||
EventResult::RepaintAsap => {
|
||||
EventResult::RepaintNow => {
|
||||
tracing::trace!("Repaint caused by winit::Event: {:?}", event);
|
||||
next_repaint_time = Instant::now() + Duration::from_secs(1_000_000_000);
|
||||
winit_app.paint();
|
||||
}
|
||||
EventResult::RepaintNext => {
|
||||
tracing::trace!("Repaint caused by winit::Event: {:?}", event);
|
||||
next_repaint_time = Instant::now();
|
||||
}
|
||||
@@ -188,14 +203,18 @@ fn run_and_exit(
|
||||
winit::event::Event::UserEvent(RequestRepaintEvent)
|
||||
| winit::event::Event::NewEvents(winit::event::StartCause::ResumeTimeReached {
|
||||
..
|
||||
}) => EventResult::RepaintAsap,
|
||||
}) => EventResult::RepaintNext,
|
||||
|
||||
event => winit_app.on_event(event_loop, &event),
|
||||
};
|
||||
|
||||
match event_result {
|
||||
EventResult::Wait => {}
|
||||
EventResult::RepaintAsap => {
|
||||
EventResult::RepaintNow => {
|
||||
next_repaint_time = Instant::now() + Duration::from_secs(1_000_000_000);
|
||||
winit_app.paint();
|
||||
}
|
||||
EventResult::RepaintNext => {
|
||||
next_repaint_time = Instant::now();
|
||||
}
|
||||
EventResult::RepaintAt(repaint_time) => {
|
||||
@@ -330,8 +349,9 @@ mod glow_integration {
|
||||
};
|
||||
let window_settings = epi_integration::load_window_settings(storage);
|
||||
|
||||
let window_builder =
|
||||
epi_integration::window_builder(native_options, &window_settings).with_title(title);
|
||||
let window_builder = epi_integration::window_builder(native_options, &window_settings)
|
||||
.with_title(title)
|
||||
.with_visible(false); // Keep hidden until we've painted something. See https://github.com/emilk/egui/pull/2279
|
||||
|
||||
let gl_window = unsafe {
|
||||
glutin::ContextBuilder::new()
|
||||
@@ -493,10 +513,12 @@ mod glow_integration {
|
||||
gl_window.swap_buffers().unwrap();
|
||||
}
|
||||
|
||||
integration.post_present(window);
|
||||
|
||||
let control_flow = if integration.should_close() {
|
||||
EventResult::Exit
|
||||
} else if repaint_after.is_zero() {
|
||||
EventResult::RepaintAsap
|
||||
EventResult::RepaintNext
|
||||
} else if let Some(repaint_after_instant) =
|
||||
std::time::Instant::now().checked_add(repaint_after)
|
||||
{
|
||||
@@ -538,7 +560,7 @@ mod glow_integration {
|
||||
if self.running.is_none() {
|
||||
self.init_run_state(event_loop);
|
||||
}
|
||||
EventResult::RepaintAsap
|
||||
EventResult::RepaintNow
|
||||
}
|
||||
winit::event::Event::Suspended => {
|
||||
#[cfg(target_os = "android")]
|
||||
@@ -560,11 +582,28 @@ mod glow_integration {
|
||||
|
||||
winit::event::Event::WindowEvent { event, .. } => {
|
||||
if let Some(running) = &mut self.running {
|
||||
// On Windows, if a window is resized by the user, it should repaint synchronously, inside the
|
||||
// event handler.
|
||||
//
|
||||
// If this is not done, the compositor will assume that the window does not want to redraw,
|
||||
// and continue ahead.
|
||||
//
|
||||
// In eframe's case, that causes the window to rapidly flicker, as it struggles to deliver
|
||||
// new frames to the compositor in time.
|
||||
//
|
||||
// The flickering is technically glutin or glow's fault, but we should be responding properly
|
||||
// to resizes anyway, as doing so avoids dropping frames.
|
||||
//
|
||||
// See: https://github.com/emilk/egui/issues/903
|
||||
let mut repaint_asap = false;
|
||||
|
||||
match &event {
|
||||
winit::event::WindowEvent::Focused(new_focused) => {
|
||||
self.is_focused = *new_focused;
|
||||
}
|
||||
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.
|
||||
@@ -576,6 +615,7 @@ mod glow_integration {
|
||||
new_inner_size,
|
||||
..
|
||||
} => {
|
||||
repaint_asap = true;
|
||||
running.gl_window.resize(**new_inner_size);
|
||||
}
|
||||
winit::event::WindowEvent::CloseRequested
|
||||
@@ -592,7 +632,11 @@ mod glow_integration {
|
||||
if running.integration.should_close() {
|
||||
EventResult::Exit
|
||||
} else if event_response.repaint {
|
||||
EventResult::RepaintAsap
|
||||
if repaint_asap {
|
||||
EventResult::RepaintNow
|
||||
} else {
|
||||
EventResult::RepaintNext
|
||||
}
|
||||
} else {
|
||||
EventResult::Wait
|
||||
}
|
||||
@@ -692,6 +736,7 @@ mod wgpu_integration {
|
||||
let window_settings = epi_integration::load_window_settings(storage);
|
||||
epi_integration::window_builder(native_options, &window_settings)
|
||||
.with_title(title)
|
||||
.with_visible(false) // Keep hidden until we've painted something. See https://github.com/emilk/egui/pull/2279
|
||||
.build(event_loop)
|
||||
.unwrap()
|
||||
}
|
||||
@@ -850,11 +895,12 @@ mod wgpu_integration {
|
||||
);
|
||||
|
||||
integration.post_rendering(app.as_mut(), window);
|
||||
integration.post_present(window);
|
||||
|
||||
let control_flow = if integration.should_close() {
|
||||
EventResult::Exit
|
||||
} else if repaint_after.is_zero() {
|
||||
EventResult::RepaintAsap
|
||||
EventResult::RepaintNext
|
||||
} else if let Some(repaint_after_instant) =
|
||||
std::time::Instant::now().checked_add(repaint_after)
|
||||
{
|
||||
@@ -913,7 +959,7 @@ mod wgpu_integration {
|
||||
);
|
||||
self.init_run_state(event_loop, storage, window);
|
||||
}
|
||||
EventResult::RepaintAsap
|
||||
EventResult::RepaintNow
|
||||
}
|
||||
winit::event::Event::Suspended => {
|
||||
#[cfg(target_os = "android")]
|
||||
@@ -923,11 +969,28 @@ mod wgpu_integration {
|
||||
|
||||
winit::event::Event::WindowEvent { event, .. } => {
|
||||
if let Some(running) = &mut self.running {
|
||||
// On Windows, if a window is resized by the user, it should repaint synchronously, inside the
|
||||
// event handler.
|
||||
//
|
||||
// If this is not done, the compositor will assume that the window does not want to redraw,
|
||||
// and continue ahead.
|
||||
//
|
||||
// In eframe's case, that causes the window to rapidly flicker, as it struggles to deliver
|
||||
// new frames to the compositor in time.
|
||||
//
|
||||
// The flickering is technically glutin or glow's fault, but we should be responding properly
|
||||
// to resizes anyway, as doing so avoids dropping frames.
|
||||
//
|
||||
// See: https://github.com/emilk/egui/issues/903
|
||||
let mut repaint_asap = false;
|
||||
|
||||
match &event {
|
||||
winit::event::WindowEvent::Focused(new_focused) => {
|
||||
self.is_focused = *new_focused;
|
||||
}
|
||||
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.
|
||||
@@ -942,6 +1005,7 @@ mod wgpu_integration {
|
||||
new_inner_size,
|
||||
..
|
||||
} => {
|
||||
repaint_asap = true;
|
||||
running
|
||||
.painter
|
||||
.on_window_resized(new_inner_size.width, new_inner_size.height);
|
||||
@@ -959,7 +1023,11 @@ mod wgpu_integration {
|
||||
if running.integration.should_close() {
|
||||
EventResult::Exit
|
||||
} else if event_response.repaint {
|
||||
EventResult::RepaintAsap
|
||||
if repaint_asap {
|
||||
EventResult::RepaintNow
|
||||
} else {
|
||||
EventResult::RepaintNext
|
||||
}
|
||||
} else {
|
||||
EventResult::Wait
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user