From 12ccb7d72e928d687b0e8697e36bcad2795a524f Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sun, 17 Dec 2023 23:10:20 +0100 Subject: [PATCH] Make sure pointer to `HtmlCanvasElement` doesn't change --- src/platform_impl/web/web_sys/canvas.rs | 12 +++++++++--- src/platform_impl/web/web_sys/pointer.rs | 4 ++-- src/platform_impl/web/window.rs | 1 + 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 5cece3889ff..8d60f49a1ee 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -1,4 +1,5 @@ use std::cell::Cell; +use std::ops::Deref; use std::rc::Rc; use std::sync::{Arc, Mutex}; @@ -49,7 +50,8 @@ pub struct Common { pub window: web_sys::Window, pub document: Document, /// Note: resizing the HTMLCanvasElement should go through `backend::set_canvas_size` to ensure the DPI factor is maintained. - pub raw: HtmlCanvasElement, + /// Note: this is read-only because we use a pointer to this for [`WindowHandle`](rwh_06::WindowHandle). + raw: Rc, style: Style, old_size: Rc>>, current_size: Rc>>, @@ -101,7 +103,7 @@ impl Canvas { let common = Common { window: window.clone(), document: document.clone(), - raw: canvas.clone(), + raw: Rc::new(canvas.clone()), style, old_size: Rc::default(), current_size: Rc::default(), @@ -539,7 +541,11 @@ impl Common { E: 'static + AsRef + wasm_bindgen::convert::FromWasmAbi, F: 'static + FnMut(E), { - EventListenerHandle::new(self.raw.clone(), event_name, Closure::new(handler)) + EventListenerHandle::new(self.raw.deref().clone(), event_name, Closure::new(handler)) + } + + pub fn raw(&self) -> &HtmlCanvasElement { + &self.raw } } diff --git a/src/platform_impl/web/web_sys/pointer.rs b/src/platform_impl/web/web_sys/pointer.rs index 71f128a959e..dbfe3476a7f 100644 --- a/src/platform_impl/web/web_sys/pointer.rs +++ b/src/platform_impl/web/web_sys/pointer.rs @@ -117,7 +117,7 @@ impl PointerHandler { T: 'static + FnMut(ModifiersState, i32, PhysicalPosition, Force), { let window = canvas_common.window.clone(); - let canvas = canvas_common.raw.clone(); + let canvas = canvas_common.raw().clone(); self.on_pointer_press = Some(canvas_common.add_event( "pointerdown", move |event: PointerEvent| { @@ -174,7 +174,7 @@ impl PointerHandler { B: 'static + FnMut(ModifiersState, i32, PhysicalPosition, ButtonsState, MouseButton), { let window = canvas_common.window.clone(); - let canvas = canvas_common.raw.clone(); + let canvas = canvas_common.raw().clone(); self.on_cursor_move = Some(canvas_common.add_event( "pointermove", move |event: PointerEvent| { diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index bd88f0763c3..8b7fb75949d 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -93,6 +93,7 @@ impl Window { .value() .map(|inner| { let canvas = inner.canvas.borrow(); + // SAFETY: This will only work if the reference to `HtmlCanvasElement` stays valid. let canvas: &wasm_bindgen::JsValue = canvas.raw(); let window_handle = rwh_06::WebCanvasWindowHandle::new(std::ptr::NonNull::from(canvas).cast());