Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eframe web: detect and report panics during startup #2992

Merged
Prev Previous commit
Next Next commit
Don't paint until first animation frame
emilk committed May 16, 2023
commit 171dbd70ddbd84c5ad5c15fbf1fa4c0b1caace55
48 changes: 26 additions & 22 deletions crates/eframe/src/web/events.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,11 @@
use super::*;

// ------------------------------------------------------------------------

/// Calls `request_animation_frame` to schedule repaint.
///
/// It will only paint if needed, but will always call `request_animation_frame` immediately.
pub fn paint_and_schedule(runner_ref: &WebRunner) -> Result<(), JsValue> {
fn paint_if_needed(runner: &mut AppRunner) -> Result<(), JsValue> {
if runner.needs_repaint.when_to_repaint() <= now_sec() {
runner.needs_repaint.clear();
let (repaint_after, clipped_primitives) = runner.logic();
runner.paint(&clipped_primitives)?;
runner
.needs_repaint
.repaint_after(repaint_after.as_secs_f64());
runner.auto_save_if_needed();
}
Ok(())
}

fn request_animation_frame(runner_ref: WebRunner) -> Result<(), JsValue> {
let window = web_sys::window().unwrap();
let closure = Closure::once(move || paint_and_schedule(&runner_ref));
window.request_animation_frame(closure.as_ref().unchecked_ref())?;
closure.forget(); // We must forget it, or else the callback is canceled on drop
Ok(())
}

fn paint_and_schedule(runner_ref: &WebRunner) -> Result<(), JsValue> {
// Only paint and schedule if there has been no panic
if let Some(mut runner_lock) = runner_ref.try_lock() {
paint_if_needed(&mut runner_lock)?;
@@ -35,6 +16,29 @@ pub fn paint_and_schedule(runner_ref: &WebRunner) -> Result<(), JsValue> {
Ok(())
}

fn paint_if_needed(runner: &mut AppRunner) -> Result<(), JsValue> {
if runner.needs_repaint.when_to_repaint() <= now_sec() {
runner.needs_repaint.clear();
let (repaint_after, clipped_primitives) = runner.logic();
runner.paint(&clipped_primitives)?;
runner
.needs_repaint
.repaint_after(repaint_after.as_secs_f64());
runner.auto_save_if_needed();
}
Ok(())
}

pub fn request_animation_frame(runner_ref: WebRunner) -> Result<(), JsValue> {
let window = web_sys::window().unwrap();
let closure = Closure::once(move || paint_and_schedule(&runner_ref));
window.request_animation_frame(closure.as_ref().unchecked_ref())?;
closure.forget(); // We must forget it, or else the callback is canceled on drop
Ok(())
}

// ------------------------------------------------------------------------

pub fn install_document_events(runner_ref: &WebRunner) -> Result<(), JsValue> {
let document = web_sys::window().unwrap().document().unwrap();

5 changes: 3 additions & 2 deletions crates/eframe/src/web/web_runner.rs
Original file line number Diff line number Diff line change
@@ -62,16 +62,17 @@ impl WebRunner {
runner.warm_up();
self.runner.replace(Some(runner));

// Install events:
{
events::install_canvas_events(self)?;
events::install_document_events(self)?;
events::install_window_events(self)?;
super::text_agent::install_text_agent(self)?;

if follow_system_theme {
events::install_color_scheme_change_event(self)?;
}
events::paint_and_schedule(self)?;

events::request_animation_frame(self.clone())?;
}

Ok(())