From 3b4e064a077f4f5add132aa448ef884c40d5a014 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 12 Jun 2024 00:22:03 +0200 Subject: [PATCH] Web: fix crash `InnerSizeWriter::request_inner_size()` (#3727) --- src/changelog/unreleased.md | 1 + src/platform_impl/web/web_sys/canvas.rs | 4 +- .../web/web_sys/resize_scaling.rs | 49 +++++++++---------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index 50f46de40f..73486cdf4d 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -50,6 +50,7 @@ changelog entry. - On Web, fix `EventLoopProxy::send_event()` triggering event loop immediately when not called from inside the event loop. Now queues a microtask instead. - On Web, stop overwriting default cursor with `CursorIcon::Default`. +- On Web, prevent crash when using `InnerSizeWriter::request_inner_size()`. ### Removed diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 0450ba8e0d..644ef76c8b 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -427,8 +427,8 @@ impl Canvas { pub(crate) fn on_resize_scale(&mut self, scale_handler: S, size_handler: R) where - S: 'static + FnMut(PhysicalSize, f64), - R: 'static + FnMut(PhysicalSize), + S: 'static + Fn(PhysicalSize, f64), + R: 'static + Fn(PhysicalSize), { self.on_resize_scale = Some(ResizeScaleHandle::new( self.window().clone(), diff --git a/src/platform_impl/web/web_sys/resize_scaling.rs b/src/platform_impl/web/web_sys/resize_scaling.rs index e22fba54b8..fdfda75acd 100644 --- a/src/platform_impl/web/web_sys/resize_scaling.rs +++ b/src/platform_impl/web/web_sys/resize_scaling.rs @@ -16,7 +16,7 @@ use super::media_query_handle::MediaQueryListHandle; use std::cell::{Cell, RefCell}; use std::rc::Rc; -pub struct ResizeScaleHandle(Rc>); +pub struct ResizeScaleHandle(Rc); impl ResizeScaleHandle { pub(crate) fn new( @@ -28,8 +28,8 @@ impl ResizeScaleHandle { resize_handler: R, ) -> Self where - S: 'static + FnMut(PhysicalSize, f64), - R: 'static + FnMut(PhysicalSize), + S: 'static + Fn(PhysicalSize, f64), + R: 'static + Fn(PhysicalSize), { Self(ResizeScaleInternal::new( window, @@ -42,7 +42,7 @@ impl ResizeScaleHandle { } pub(crate) fn notify_resize(&self) { - self.0.borrow_mut().notify() + self.0.notify() } } @@ -53,11 +53,11 @@ struct ResizeScaleInternal { document: Document, canvas: HtmlCanvasElement, style: Style, - mql: MediaQueryListHandle, + mql: RefCell, observer: ResizeObserver, _observer_closure: Closure, - scale_handler: Box, f64)>, - resize_handler: Box)>, + scale_handler: Box, f64)>, + resize_handler: Box)>, notify_scale: Cell, } @@ -69,12 +69,12 @@ impl ResizeScaleInternal { style: Style, scale_handler: S, resize_handler: R, - ) -> Rc> + ) -> Rc where - S: 'static + FnMut(PhysicalSize, f64), - R: 'static + FnMut(PhysicalSize), + S: 'static + Fn(PhysicalSize, f64), + R: 'static + Fn(PhysicalSize), { - Rc::>::new_cyclic(|weak_self| { + Rc::::new_cyclic(|weak_self| { let mql = Self::create_mql(&window, { let weak_self = weak_self.clone(); move |mql| { @@ -86,9 +86,7 @@ impl ResizeScaleInternal { let weak_self = weak_self.clone(); let observer_closure = Closure::new(move |entries: Array, _| { - if let Some(rc_self) = weak_self.upgrade() { - let mut this = rc_self.borrow_mut(); - + if let Some(this) = weak_self.upgrade() { let size = this.process_entry(entries); if this.notify_scale.replace(false) { @@ -101,18 +99,18 @@ impl ResizeScaleInternal { }); let observer = Self::create_observer(&canvas, observer_closure.as_ref()); - RefCell::new(Self { + Self { window, document, canvas, style, - mql, + mql: RefCell::new(mql), observer, _observer_closure: observer_closure, scale_handler: Box::new(scale_handler), resize_handler: Box::new(resize_handler), notify_scale: Cell::new(false), - }) + } }) } @@ -152,7 +150,7 @@ impl ResizeScaleInternal { observer } - fn notify(&mut self) { + fn notify(&self) { if !self.document.contains(Some(&self.canvas)) || self.style.get("display") == "none" { let size = PhysicalSize::new(0, 0); @@ -200,10 +198,9 @@ impl ResizeScaleInternal { } } - fn handle_scale(this: Rc>, mql: &MediaQueryList) { - let weak_self = Rc::downgrade(&this); - let mut this = this.borrow_mut(); - let scale = super::scale_factor(&this.window); + fn handle_scale(self: Rc, mql: &MediaQueryList) { + let weak_self = Rc::downgrade(&self); + let scale = super::scale_factor(&self.window); // TODO: confirm/reproduce this problem, see: // . @@ -217,15 +214,15 @@ impl ResizeScaleInternal { return; } - let new_mql = Self::create_mql(&this.window, move |mql| { + let new_mql = Self::create_mql(&self.window, move |mql| { if let Some(rc_self) = weak_self.upgrade() { Self::handle_scale(rc_self, mql); } }); - this.mql = new_mql; + self.mql.replace(new_mql); - this.notify_scale.set(true); - this.notify(); + self.notify_scale.set(true); + self.notify(); } fn process_entry(&self, entries: Array) -> PhysicalSize {