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

Run no egui pass in the web backend when the tab is hidden

Same as the native backends: tick `App::logic` via `Context::run_logic`
and leave all ui state alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Emil Ernerfeldt
2026-08-04 17:24:45 +02:00
parent 3f3882612b
commit 49d69a19dd

View File

@@ -280,12 +280,31 @@ impl AppRunner {
.and_then(|v| v.visible()) .and_then(|v| v.visible())
.unwrap_or(true); .unwrap_or(true);
let full_output = self.egui_ctx.run_ui(raw_input, |ui| { if !is_visible {
self.app.logic(ui.ctx(), &mut self.frame); // The tab is hidden, so we run no egui pass at all.
// That way all ui state is left untouched, and is still there
// when the tab is shown again.
if is_visible { // No pass will consume the input, so save it for the next one:
self.app.ui(ui, &mut self.frame); self.input.raw.append(raw_input);
let egui::LogicOutput {
platform_output,
viewport_commands,
} = self.egui_ctx.run_logic(|ctx| {
self.app.logic(ctx, &mut self.frame);
});
self.handle_viewport_commands(viewport_commands.into_values().flatten());
self.handle_platform_output(platform_output);
return;
} }
// `App::logic` may not show any ui, so it is called outside of the pass:
self.app.logic(&self.egui_ctx, &mut self.frame);
let full_output = self.egui_ctx.run_ui(raw_input, |ui| {
self.app.ui(ui, &mut self.frame);
}); });
let egui::FullOutput { let egui::FullOutput {
platform_output, platform_output,
@@ -298,8 +317,19 @@ impl AppRunner {
if viewport_output.len() > 1 { if viewport_output.len() > 1 {
log::warn!("Multiple viewports not yet supported on the web"); log::warn!("Multiple viewports not yet supported on the web");
} }
for (_viewport_id, viewport_output) in viewport_output { self.handle_viewport_commands(
for command in viewport_output.commands { viewport_output
.into_values()
.flat_map(|viewport_output| viewport_output.commands),
);
self.handle_platform_output(platform_output);
self.textures_delta.append(textures_delta);
self.clipped_primitives = Some(self.egui_ctx.tessellate(shapes, pixels_per_point));
}
fn handle_viewport_commands(&mut self, commands: impl Iterator<Item = ViewportCommand>) {
for command in commands {
match command { match command {
ViewportCommand::Screenshot(user_data) => { ViewportCommand::Screenshot(user_data) => {
self.screenshot_commands_with_frame_delay self.screenshot_commands_with_frame_delay
@@ -315,13 +345,6 @@ impl AppRunner {
} }
} }
self.handle_platform_output(platform_output);
if is_visible || !textures_delta.is_empty() {
self.textures_delta.append(textures_delta);
self.clipped_primitives = Some(self.egui_ctx.tessellate(shapes, pixels_per_point));
}
}
/// Paint the results of the last call to [`Self::logic`]. /// Paint the results of the last call to [`Self::logic`].
pub fn paint(&mut self) { pub fn paint(&mut self) {
let clipped_primitives = std::mem::take(&mut self.clipped_primitives); let clipped_primitives = std::mem::take(&mut self.clipped_primitives);