From 8cd3aaa8a2edb81df47cb6febe7e86adbbf82555 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 22 Dec 2023 22:33:50 +0100 Subject: [PATCH] On Web, use the new `WebCanvasWindowHandle` (#3270) --- CHANGELOG.md | 1 + src/platform_impl/ios/window.rs | 14 +++++++++-- src/platform_impl/macos/window.rs | 14 +++++++++-- .../web/event_loop/window_target.rs | 1 + src/platform_impl/web/web_sys/canvas.rs | 12 +++++++--- src/platform_impl/web/web_sys/pointer.rs | 4 ++-- src/platform_impl/web/window.rs | 23 +++++++++++++------ src/window.rs | 5 +--- 8 files changed, 54 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02f7e559..820d3e84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Unreleased` header. - On macOS, add services menu. - **Breaking:** On Web, remove queuing fullscreen request in absence of transient activation. - On Web, fix setting cursor icon overriding cursor visibility. +- **Breaking:** On Web, return `RawWindowHandle::WebCanvas` instead of `RawWindowHandle::Web`. # 0.29.5 diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index 765dea50..692e70b1 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -360,14 +360,14 @@ impl Inner { } #[cfg(feature = "rwh_06")] - pub fn raw_window_handle_rwh_06(&self) -> Result { + pub fn raw_window_handle_rwh_06(&self) -> rwh_06::RawWindowHandle { let mut window_handle = rwh_06::UiKitWindowHandle::new({ let ui_view = Id::as_ptr(&self.view) as _; std::ptr::NonNull::new(ui_view).expect("Id should never be null") }); window_handle.ui_view_controller = std::ptr::NonNull::new(Id::as_ptr(&self.view_controller) as _); - Ok(rwh_06::RawWindowHandle::UiKit(window_handle)) + rwh_06::RawWindowHandle::UiKit(window_handle) } #[cfg(feature = "rwh_06")] @@ -523,6 +523,16 @@ impl Window { pub(crate) fn maybe_wait_on_main(&self, f: impl FnOnce(&Inner) -> R + Send) -> R { self.inner.get_on_main(|inner, _mtm| f(inner)) } + + #[cfg(feature = "rwh_06")] + #[inline] + pub(crate) fn raw_window_handle_rwh_06( + &self, + ) -> Result { + Ok(self + .maybe_wait_on_main(|w| crate::SendSyncWrapper(w.raw_window_handle_rwh_06())) + .0) + } } // WindowExtIOS diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 3ca959d6..9fe312a4 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -89,6 +89,16 @@ impl Window { ) -> R { self.window.get_on_main(|window, _mtm| f(window)) } + + #[cfg(feature = "rwh_06")] + #[inline] + pub(crate) fn raw_window_handle_rwh_06( + &self, + ) -> Result { + Ok(self + .maybe_wait_on_main(|w| crate::SendSyncWrapper(w.raw_window_handle_rwh_06())) + .0) + } } #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -1386,12 +1396,12 @@ impl WinitWindow { #[cfg(feature = "rwh_06")] #[inline] - pub fn raw_window_handle_rwh_06(&self) -> Result { + pub fn raw_window_handle_rwh_06(&self) -> rwh_06::RawWindowHandle { let window_handle = rwh_06::AppKitWindowHandle::new({ let ptr = Id::as_ptr(&self.contentView()) as *mut _; std::ptr::NonNull::new(ptr).expect("Id should never be null") }); - Ok(rwh_06::RawWindowHandle::AppKit(window_handle)) + rwh_06::RawWindowHandle::AppKit(window_handle) } #[cfg(feature = "rwh_06")] diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index 11da79fc..1921c6a7 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -83,6 +83,7 @@ impl EventLoopWindowTarget { ) { let canvas_clone = canvas.clone(); let mut canvas = canvas.borrow_mut(); + #[cfg(any(feature = "rwh_04", feature = "rwh_05"))] canvas.set_attribute("data-raw-handle", &id.0.to_string()); canvas.on_touch_start(prevent_default); diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 5cece388..8d60f49a 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 71f128a9..dbfe3476 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 658ae659..8b7fb759 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -85,6 +85,22 @@ impl Window { .value() .map(|inner| inner.canvas.borrow().raw().clone()) } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_window_handle_rwh_06(&self) -> Result { + self.inner + .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()); + rwh_06::RawWindowHandle::WebCanvas(window_handle) + }) + .ok_or(rwh_06::HandleError::Unavailable) + } } impl Inner { @@ -378,13 +394,6 @@ impl Inner { rwh_05::RawDisplayHandle::Web(rwh_05::WebDisplayHandle::empty()) } - #[cfg(feature = "rwh_06")] - #[inline] - pub fn raw_window_handle_rwh_06(&self) -> Result { - let window_handle = rwh_06::WebWindowHandle::new(self.id.0); - Ok(rwh_06::RawWindowHandle::Web(window_handle)) - } - #[cfg(feature = "rwh_06")] #[inline] pub fn raw_display_handle_rwh_06( diff --git a/src/window.rs b/src/window.rs index e5e22c18..e1d0ac34 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1530,10 +1530,7 @@ impl Window { #[cfg(feature = "rwh_06")] impl rwh_06::HasWindowHandle for Window { fn window_handle(&self) -> Result, rwh_06::HandleError> { - let raw = self - .window - .maybe_wait_on_main(|w| w.raw_window_handle_rwh_06().map(SendSyncWrapper))? - .0; + let raw = self.window.raw_window_handle_rwh_06()?; // SAFETY: The window handle will never be deallocated while the window is alive. Ok(unsafe { rwh_06::WindowHandle::borrow_raw(raw) })