diff --git a/crates/eframe/src/web/app_runner.rs b/crates/eframe/src/web/app_runner.rs index 5a0ead01300..e8f771bdfda 100644 --- a/crates/eframe/src/web/app_runner.rs +++ b/crates/eframe/src/web/app_runner.rs @@ -173,20 +173,8 @@ impl AppRunner { self.painter.destroy(); } - /// Runs the user code and paints the UI. - /// - /// If there is already an outstanding frame of output, - /// that is painted instead. - pub fn run_and_paint(&mut self) { - if self.clipped_primitives.is_none() { - // Run user code, and paint the results: - self.logic(); - self.paint(); - } else { - // We have already run the logic, e.g. in an on-click event, - // so let's only present the results: - self.paint(); - } + pub fn has_outstanding_paint_data(&self) -> bool { + self.clipped_primitives.is_some() } /// Runs the logic, but doesn't paint the result. diff --git a/crates/eframe/src/web/events.rs b/crates/eframe/src/web/events.rs index bd8bc88a680..9bb5c0f885a 100644 --- a/crates/eframe/src/web/events.rs +++ b/crates/eframe/src/web/events.rs @@ -17,8 +17,25 @@ fn paint_and_schedule(runner_ref: &WebRunner) -> Result<(), JsValue> { fn paint_if_needed(runner: &mut AppRunner) { if runner.needs_repaint.needs_repaint() { - runner.needs_repaint.clear(); - runner.run_and_paint(); + if runner.has_outstanding_paint_data() { + // We have already run the logic, e.g. in an on-click event, + // so let's only present the results: + runner.paint(); + + // We schedule another repaint asap, so that we can run the actual logic + // again, which may schedule a new repaint (if there's animations): + runner.needs_repaint.repaint_asap(); + } else { + // Clear the `needs_repaint` flags _before_ + // running the logic, as the logic could cause it to be set again. + runner.needs_repaint.clear(); + + // Run user code… + runner.logic(); + + // …and paint the result. + runner.paint(); + } } runner.auto_save_if_needed(); }