1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-30 21:30:03 -04:00

Fix crash when parent viewport is hidden (#8226)

Hey,
this is my fist PR to fix the bug I just published #8225 
I hope it helps. 
I tested the fix with wgpu but not glow.
I must say that I am not very happy to have very similar function
is_viewport_or_descendant_visible in both case.
Let me know if you would prefer that I try to factorize it.

* Closes <https://github.com/emilk/egui/issues/8225>
* [X] I have followed the instructions in the PR template

---------

Co-authored-by: Matthieu Casanova <public@kpouer.com>
This commit is contained in:
Matthieu Casanova
2026-06-22 03:39:53 +02:00
committed by GitHub
parent 2c8c27c5df
commit 467c5b84f0
2 changed files with 53 additions and 11 deletions

View File

@@ -558,7 +558,7 @@ impl GlowWinitRunning<'_> {
}
}
let (raw_input, viewport_ui_cb, is_visible) = {
let (raw_input, viewport_ui_cb, is_visible, run_ui) = {
let mut glutin = self.glutin.borrow_mut();
let egui_ctx = glutin.egui_ctx.clone();
let Some(viewport) = glutin.viewports.get_mut(&viewport_id) else {
@@ -577,6 +577,9 @@ impl GlowWinitRunning<'_> {
let mut raw_input = egui_winit.take_egui_input(window);
let viewport_ui_cb = viewport.viewport_ui_cb.clone();
let run_ui =
is_visible || is_viewport_or_descendant_visible(&glutin.viewports, viewport_id);
self.integration.pre_update();
raw_input.time = Some(self.integration.beginning.elapsed().as_secs_f64());
@@ -586,7 +589,7 @@ impl GlowWinitRunning<'_> {
.map(|(id, viewport)| (*id, viewport.info.clone()))
.collect();
(raw_input, viewport_ui_cb, is_visible)
(raw_input, viewport_ui_cb, is_visible, run_ui)
};
// HACK: In order to get the right clear_color, the system theme needs to be set, which
@@ -641,7 +644,7 @@ impl GlowWinitRunning<'_> {
self.app.as_mut(),
viewport_ui_cb.as_deref(),
raw_input,
is_visible,
run_ui,
);
// ------------------------------------------------------------
@@ -1462,6 +1465,28 @@ fn initialize_or_update_viewport(
}
}
/// Is this viewport, or any of its (transitive) descendant viewports, visible?
///
/// Immediate viewports are rendered inline while their parent's UI runs, so even
/// if this viewport's window is occluded or minimized we must still run its UI to
/// give any visible descendant a chance to be painted.
fn is_viewport_or_descendant_visible(
viewports: &OrderedViewportIdMap<Viewport>,
viewport_id: ViewportId,
) -> bool {
let Some(viewport) = viewports.get(&viewport_id) else {
return false;
};
if viewport.info.visible().unwrap_or(true) {
return true;
}
viewports.values().any(|child| {
child.ids.parent == viewport_id
&& child.ids.this != viewport_id // ROOT is its own parent; avoid self-recursion.
&& is_viewport_or_descendant_visible(viewports, child.ids.this)
})
}
/// This is called (via a callback) by user code to render immediate viewports,
/// i.e. viewport that are directly nested inside a parent viewport.
fn render_immediate_viewport(