Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion crates/eframe/src/native/glow_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ struct Viewport {
/// None for immediate viewports.
viewport_ui_cb: Option<Arc<DeferredViewportUiCallback>>,

/// When `true`, the window was created hidden to avoid a white flash.
/// It will be shown after the first frame is painted.
/// See <https://github.com/emilk/egui/issues/3625>
needs_first_show: bool,

// These three live and die together.
// TODO(emilk): clump them together into one struct!
gl_surface: Option<glutin::surface::Surface<glutin::surface::WindowSurface>>,
Expand Down Expand Up @@ -755,6 +760,14 @@ impl GlowWinitRunning<'_> {
}
}

// Show viewport after the first frame has been painted to prevent white flash.
// See https://github.com/emilk/egui/issues/3625
if let Some(viewport) = viewports.get_mut(&viewport_id) {
if std::mem::take(&mut viewport.needs_first_show) {
window.set_visible(true);
}
}

glutin.handle_viewport_output(event_loop, &integration.egui_ctx, &viewport_output);

integration.report_frame_time(frame_timer.total_time_sec()); // don't count auto-save time as part of regular frame time
Expand Down Expand Up @@ -1097,6 +1110,7 @@ impl GlutinWindowContext {
info: viewport_info,
actions_requested: Default::default(),
viewport_ui_cb: None,
needs_first_show: false, // Root window visibility is handled by EpiIntegration::post_rendering
gl_surface: None,
window: window.map(Arc::new),
egui_winit: None,
Expand Down Expand Up @@ -1159,9 +1173,20 @@ impl GlutinWindowContext {
window
} else {
log::debug!("Creating a window for viewport {viewport_id:?}");

// Start non-root viewports hidden to prevent a white flash.
// They will be shown after the first frame is painted.
// The root viewport is handled separately by EpiIntegration::post_rendering.
// See https://github.com/emilk/egui/issues/3625
let mut builder = viewport.builder.clone();
if viewport_id != ViewportId::ROOT && builder.visible.unwrap_or(true) {
builder.visible = Some(false);
viewport.needs_first_show = true;
}

let window_attributes = egui_winit::create_winit_window_attributes(
&self.egui_ctx,
viewport.builder.clone(),
builder,
);
if window_attributes.transparent()
&& self.gl_config.supports_transparency() == Some(false)
Expand Down Expand Up @@ -1413,6 +1438,7 @@ fn initialize_or_update_viewport(
info: Default::default(),
actions_requested: Default::default(),
viewport_ui_cb,
needs_first_show: false, // Set to true in initialize_window when window is created
window: None,
egui_winit: None,
gl_surface: None,
Expand Down Expand Up @@ -1585,6 +1611,12 @@ fn render_immediate_viewport(
}
}

// Show viewport after the first frame has been painted to prevent white flash.
// See https://github.com/emilk/egui/issues/3625
if std::mem::take(&mut viewport.needs_first_show) {
window.set_visible(true);
}

egui_winit.handle_platform_output(window, platform_output);

event_loop_context::with_current_event_loop(|event_loop| {
Expand Down
37 changes: 36 additions & 1 deletion crates/eframe/src/native/wgpu_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ pub struct Viewport {
/// `None` for sync viewports.
viewport_ui_cb: Option<Arc<DeferredViewportUiCallback>>,

/// When `true`, the window was created hidden to avoid a white flash.
/// It will be shown after the first frame is painted.
/// See <https://github.com/emilk/egui/issues/3625>
needs_first_show: bool,

/// Window surface state that's initialized when the app starts running via a Resumed event
/// and on Android will also be destroyed if the application is paused.
window: Option<Arc<Window>>,
Expand Down Expand Up @@ -305,6 +310,7 @@ impl<'app> WgpuWinitApp<'app> {
info: viewport_info,
actions_requested: Default::default(),
viewport_ui_cb: None,
needs_first_show: false, // Root window visibility is handled by EpiIntegration::post_rendering
window: Some(window),
egui_winit: Some(egui_winit),
},
Expand Down Expand Up @@ -745,6 +751,16 @@ impl WgpuWinitRunning<'_> {
0.0
};

// Show viewport after the first frame has been painted to prevent white flash.
// See https://github.com/emilk/egui/issues/3625
if let Some(viewport) = viewports.get_mut(&viewport_id) {
if std::mem::take(&mut viewport.needs_first_show) {
if let Some(window) = &viewport.window {
window.set_visible(true);
}
}
}

let active_viewports_ids: ViewportIdSet = viewport_output.keys().copied().collect();

handle_viewport_output(
Expand Down Expand Up @@ -942,7 +958,17 @@ impl Viewport {

let viewport_id = self.ids.this;

match egui_winit::create_window(egui_ctx, event_loop, &self.builder) {
// Start non-root viewports hidden to prevent a white flash.
// They will be shown after the first frame is painted.
// The root viewport is handled separately by EpiIntegration::post_rendering.
// See https://github.com/emilk/egui/issues/3625
let mut builder = self.builder.clone();
if viewport_id != ViewportId::ROOT && builder.visible.unwrap_or(true) {
builder.visible = Some(false);
self.needs_first_show = true;
}

match egui_winit::create_window(egui_ctx, event_loop, &builder) {
Ok(window) => {
windows_id.insert(window.id(), viewport_id);

Expand Down Expand Up @@ -1102,6 +1128,14 @@ fn render_immediate_viewport(

egui_winit.handle_platform_output(window, platform_output);

// Show viewport after the first frame has been painted to prevent white flash.
// See https://github.com/emilk/egui/issues/3625
if std::mem::take(&mut viewport.needs_first_show) {
if let Some(window) = &viewport.window {
window.set_visible(true);
}
}

handle_viewport_output(
&egui_ctx,
&viewport_output,
Expand Down Expand Up @@ -1212,6 +1246,7 @@ fn initialize_or_update_viewport<'a>(
info: Default::default(),
actions_requested: Vec::new(),
viewport_ui_cb,
needs_first_show: false, // Set to true in initialize_window when window is created
window: None,
egui_winit: None,
})
Expand Down
Loading