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

Fix crash on request_animation_frame when destroying web runner (#4169)

Previously, any frames in flight (`requestAnimationFrame`) on web were
not being cancelled (`cancelAnimationFrame`) when `WebRunner::destroy`
was called. If a user called `destroy`, then immediately removed the
canvas from the DOM, eframe could panic with a "failed to find (canvas)
element by id" error message.

This PR changes two things:
- The canvas element is directly referenced everywhere it's needed
instead of being looked up by `canvas_id`[^1]
- The RAF handle is stored in `WebRunner` and `cancelAnimationFrame` is
called on it inside of `WebRunner::destroy`[^2]

[^1]: The WebGL/WGPU backends were already holding onto the canvas (and
associated GPU context), so the change is just converting all the
`get_element_by_id` lookups to retrieve the canvas from the web runner
handle.

[^2]: There is only ever one frame in flight, so we store it directly as
a scalar field.
This commit is contained in:
Jan Procházka
2024-03-14 10:26:34 +01:00
committed by GitHub
parent 00e8ce6d7e
commit c5eaba43cd
9 changed files with 73 additions and 61 deletions

View File

@@ -165,8 +165,8 @@ impl AppRunner {
self.last_save_time = now_sec();
}
pub fn canvas_id(&self) -> &str {
self.painter.canvas_id()
pub fn canvas(&self) -> &web_sys::HtmlCanvasElement {
self.painter.canvas()
}
pub fn destroy(mut self) {
@@ -182,8 +182,8 @@ impl AppRunner {
///
/// The result can be painted later with a call to [`Self::run_and_paint`] or [`Self::paint`].
pub fn logic(&mut self) {
super::resize_canvas_to_screen_size(self.canvas_id(), self.web_options.max_size_points);
let canvas_size = super::canvas_size_in_points(self.canvas_id());
super::resize_canvas_to_screen_size(self.canvas(), self.web_options.max_size_points);
let canvas_size = super::canvas_size_in_points(self.canvas());
let raw_input = self.input.new_frame(canvas_size);
let full_output = self.egui_ctx.run(raw_input, |egui_ctx| {
@@ -268,7 +268,7 @@ impl AppRunner {
self.mutable_text_under_cursor = mutable_text_under_cursor;
if self.ime != ime {
super::text_agent::move_text_cursor(ime, self.canvas_id());
super::text_agent::move_text_cursor(ime, self.canvas());
self.ime = ime;
}
}