diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index 28c7f318cf..07628e7a50 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -355,14 +355,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")] @@ -518,6 +518,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 7e7d6f383e..1c931d6359 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -88,6 +88,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)] @@ -1378,12 +1388,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 6fd9d8635c..0d3ea2d2de 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -84,6 +84,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 908a2c0423..ab71595751 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, Weak}; use std::sync::{Arc, Mutex}; @@ -50,7 +51,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: CssStyleDeclaration, old_size: Rc>>, current_size: Rc>>, @@ -102,7 +104,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(), @@ -552,7 +554,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 } // The difference between add_event and add_user_event is that the latter has a special meaning diff --git a/src/platform_impl/web/web_sys/pointer.rs b/src/platform_impl/web/web_sys/pointer.rs index 4605d0aca0..1ed6dc3e15 100644 --- a/src/platform_impl/web/web_sys/pointer.rs +++ b/src/platform_impl/web/web_sys/pointer.rs @@ -117,8 +117,8 @@ impl PointerHandler { T: 'static + FnMut(ModifiersState, i32, PhysicalPosition, Force), { let window = canvas_common.window.clone(); - let canvas = canvas_common.raw.clone(); - self.on_pointer_press = Some(canvas_common.add_transient_event( + let canvas = canvas_common.raw().clone(); + self.on_pointer_press = Some(canvas_common.add_event( "pointerdown", move |event: PointerEvent| { if prevent_default { @@ -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 7d54528702..ac0bfa294a 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -82,6 +82,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 { @@ -379,13 +395,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 333051eacd..ec49cc67b8 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1517,10 +1517,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) })