eframe: Don't show window until after initialization (#2279)

* Don't show window until after initialization

Shortens #1802, but does not completely solve it

* format code

* Present first frame immediately before showing window

This resolves the white flash almost completely, but is a hack. Window
visibility should be derived from the AppOutput, and the first frame
should not be painted before the event loop has processed initial
events.

Working on a better implementation.

* Integrate window showing with AppOutput

This allows an app to keep the window hidden (never shown) by calling
Frame.set_visible(false) on the first update. This includes a slightly
less nasty hack than the last commit did.

Also fixes an accidental cross-contamination of pull requests.

* fmt

* add comments

* add comments

* add comments

* add comments

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
LoganDark 2022-11-13 11:30:52 -08:00 committed by GitHub
parent 5bac853d9c
commit f0f41d60e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 8 deletions

View file

@ -146,7 +146,7 @@ pub fn handle_app_output(
fullscreen,
drag_window,
window_pos,
visible,
visible: _, // handled in post_present
always_on_top,
} = app_output;
@ -183,10 +183,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);
}
@ -240,7 +236,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,
@ -325,6 +324,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);
}
@ -341,6 +341,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,

View file

@ -349,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()
@ -512,6 +513,8 @@ 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() {
@ -733,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()
}
@ -891,6 +895,7 @@ mod wgpu_integration {
);
integration.post_rendering(app.as_mut(), window);
integration.post_present(window);
let control_flow = if integration.should_close() {
EventResult::Exit