From 4e71da45ae40ec1038618497962492bf31426f6f Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 16 Jul 2023 18:11:34 -0700 Subject: [PATCH 01/14] Add wasm-bindgen v0.2 handles --- src/lib.rs | 18 ++++++++++++++- src/web.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3b81564..d85daf4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,7 +51,9 @@ pub use unix::{ DrmDisplayHandle, DrmWindowHandle, GbmDisplayHandle, GbmWindowHandle, WaylandDisplayHandle, WaylandWindowHandle, XcbDisplayHandle, XcbWindowHandle, XlibDisplayHandle, XlibWindowHandle, }; -pub use web::{WebDisplayHandle, WebWindowHandle}; +pub use web::{ + Wbg02CanvasWindowHandle, Wbg02OffscreenCanvasWindowHandle, WebDisplayHandle, WebWindowHandle, +}; pub use windows::{Win32WindowHandle, WinRtWindowHandle, WindowsDisplayHandle}; use core::fmt; @@ -189,6 +191,20 @@ pub enum RawWindowHandle { /// ## Availability Hints /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5. Web(WebWindowHandle), + /// A raw window handle for a Web canvas registered via [`wasm-bindgen`]. + /// + /// ## Availability Hints + /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5. + /// + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + Wgb02Canvas(Wbg02CanvasWindowHandle), + /// A raw window handle for a Web offscreen canvas registered via [`wasm-bindgen`]. + /// + /// ## Availability Hints + /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5. + /// + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + Wgb02OffscreenCanvas(Wbg02OffscreenCanvasWindowHandle), /// A raw window handle for Android NDK. /// /// ## Availability Hints diff --git a/src/web.rs b/src/web.rs index 33d7e87..5bec0c0 100644 --- a/src/web.rs +++ b/src/web.rs @@ -48,3 +48,67 @@ impl WebWindowHandle { Self { id } } } + +/// Raw window handle for a Web canvas registered via [`wasm-bindgen`]. +/// +/// ## Construction +/// ``` +/// # use raw_window_handle::Wbg02CanvasWindowHandle; +/// let mut window_handle = Wbg02CanvasWindowHandle::empty(); +/// /* set fields */ +/// ``` +/// +/// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen +#[non_exhaustive] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Wbg02CanvasWindowHandle { + /// The index of the canvas element in the [`wasm-bindgen`] table. + /// + /// If this index if non-zero, it is implied that it represents an [`HtmlCanvasElement`] + /// that is registered in the [`wasm-bindgen`] table. It can be converted to and from the + /// [`HtmlCanvasElement`] using [`wasm-bindgen`]'s [`FromWasmAbi`] and [`IntoWasmAbi`] traits. + /// + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html + /// [`FromWasmAbi`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.FromWasmAbi.html + /// [`IntoWasmAbi`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.IntoWasmAbi.html + pub idx: u32, +} + +impl Wbg02CanvasWindowHandle { + pub fn empty() -> Self { + Self { idx: 0 } + } +} + +/// Raw window handle for a Web offscreen canvas registered via [`wasm-bindgen`]. +/// +/// ## Construction +/// ``` +/// # use raw_window_handle::Wbg02OffscreenCanvasWindowHandle; +/// let mut window_handle = Wbg02OffscreenCanvasWindowHandle::empty(); +/// /* set fields */ +/// ``` +/// +/// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen +#[non_exhaustive] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Wbg02OffscreenCanvasWindowHandle { + /// The index of the canvas element in the [`wasm-bindgen`] table. + /// + /// If this index if non-zero, it is implied that it represents an [`OffscreenCanvas`] + /// that is registered in the [`wasm-bindgen`] table. It can be converted to and from the + /// [`OffscreenCanvas`] using [`wasm-bindgen`]'s [`FromWasmAbi`] and [`IntoWasmAbi`] traits. + /// + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html + /// [`FromWasmAbi`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.FromWasmAbi.html + /// [`IntoWasmAbi`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.IntoWasmAbi.html + pub idx: u32, +} + +impl Wbg02OffscreenCanvasWindowHandle { + pub fn empty() -> Self { + Self { idx: 0 } + } +} From 5cca108bdc905375bae4aacfd0da6e836cb06501 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Fri, 1 Sep 2023 21:15:49 -0700 Subject: [PATCH 02/14] Replace wasm-bindgen handles with real wbg objects In response to feedback from the community, this sets up the wasm- bindgen handles to use direct wasm-bindgen objects rather than indices. As wasm-bindgen handles are not Copy, Eq or Hash, this commit also removes those impls from all handles. Closes #142 as well Signed-off-by: John Nunley --- Cargo.toml | 15 +++++++ src/android.rs | 4 +- src/appkit.rs | 4 +- src/borrowed.rs | 8 ++-- src/haiku.rs | 4 +- src/lib.rs | 5 ++- src/redox.rs | 4 +- src/uikit.rs | 4 +- src/unix.rs | 20 ++++----- src/web.rs | 113 ++++++++++++++++++++++++++++++++++++++---------- src/windows.rs | 6 +-- 11 files changed, 134 insertions(+), 53 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 675e28e..5e4b923 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,21 @@ rust-version = "1.64" alloc = [] std = ["alloc"] +# Unstable feature to allow the use of `wasm-bindgen` in the `wasm` target. +# +# This is radioactive semver-wise. Do not rely on this in stable code. Any code enabled by this +# feature can be changed or removed in a breaking way at any time. In fact, this feature could +# be removed entirely tomorrow. +# +# The point being: rely on this at your own peril. +unstable_web_handles = ["wasm-bindgen", "std"] + +[target.'cfg(target_family = "wasm")'.dependencies.wasm-bindgen] +version = "0.2.87" +default-features = false +features = ["std"] +optional = true + [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/src/android.rs b/src/android.rs index fc10ecb..3afe70b 100644 --- a/src/android.rs +++ b/src/android.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for Android. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct AndroidDisplayHandle {} impl AndroidDisplayHandle { @@ -23,7 +23,7 @@ impl AndroidDisplayHandle { /// Raw window handle for Android NDK. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct AndroidNdkWindowHandle { /// A pointer to an `ANativeWindow`. pub a_native_window: NonNull, diff --git a/src/appkit.rs b/src/appkit.rs index 3b05810..ec9a66c 100644 --- a/src/appkit.rs +++ b/src/appkit.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for AppKit. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct AppKitDisplayHandle {} impl AppKitDisplayHandle { @@ -23,7 +23,7 @@ impl AppKitDisplayHandle { /// Raw window handle for AppKit. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct AppKitWindowHandle { /// A pointer to an `NSView` object. pub ns_view: NonNull, diff --git a/src/borrowed.rs b/src/borrowed.rs index 9e3d3a0..3c2fd91 100644 --- a/src/borrowed.rs +++ b/src/borrowed.rs @@ -84,7 +84,7 @@ impl HasDisplayHandle for alloc::sync::Arc { /// /// Get the underlying raw display handle with the [`HasRawDisplayHandle`] trait. #[repr(transparent)] -#[derive(PartialEq, Eq, Hash, Copy, Clone)] +#[derive(PartialEq, Clone)] pub struct DisplayHandle<'a> { raw: RawDisplayHandle, _marker: PhantomData<&'a *const ()>, @@ -112,13 +112,13 @@ impl<'a> DisplayHandle<'a> { unsafe impl HasRawDisplayHandle for DisplayHandle<'_> { fn raw_display_handle(&self) -> Result { - Ok(self.raw) + Ok(self.raw.clone()) } } impl<'a> HasDisplayHandle for DisplayHandle<'a> { fn display_handle(&self) -> Result, HandleError> { - Ok(*self) + Ok(self.clone()) } } @@ -209,7 +209,7 @@ impl HasWindowHandle for alloc::sync::Arc { /// /// This handle is guaranteed to be safe and valid. Get the underlying raw window handle with the /// [`HasRawWindowHandle`] trait. -#[derive(PartialEq, Eq, Hash, Clone)] +#[derive(PartialEq, Clone)] pub struct WindowHandle<'a> { raw: RawWindowHandle, _marker: PhantomData<&'a *const ()>, diff --git a/src/haiku.rs b/src/haiku.rs index ef010ee..f35696b 100644 --- a/src/haiku.rs +++ b/src/haiku.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for Haiku. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct HaikuDisplayHandle {} impl HaikuDisplayHandle { @@ -23,7 +23,7 @@ impl HaikuDisplayHandle { /// Raw window handle for Haiku. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct HaikuWindowHandle { /// A pointer to a BWindow object pub b_window: NonNull, diff --git a/src/lib.rs b/src/lib.rs index d85daf4..9aa7bc9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] +#![allow(clippy::new_without_default)] //! Interoperability library for Rust Windowing applications. //! @@ -122,7 +123,7 @@ unsafe impl HasRawWindowHandle for alloc::sync:: /// [`RawWindowHandle::Xlib`] on macOS, it would just be weird, and probably /// requires something like XQuartz be used). #[non_exhaustive] -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub enum RawWindowHandle { /// A raw window handle for UIKit (Apple's non-macOS windowing library). /// @@ -290,7 +291,7 @@ unsafe impl HasRawDisplayHandle for alloc::sync /// [`RawDisplayHandle::Xlib`] on macOS, it would just be weird, and probably /// requires something like XQuartz be used). #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub enum RawDisplayHandle { /// A raw display handle for UIKit (Apple's non-macOS windowing library). /// diff --git a/src/redox.rs b/src/redox.rs index 7562756..6a65977 100644 --- a/src/redox.rs +++ b/src/redox.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for the Redox operating system. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct OrbitalDisplayHandle {} impl OrbitalDisplayHandle { @@ -23,7 +23,7 @@ impl OrbitalDisplayHandle { /// Raw window handle for the Redox operating system. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct OrbitalWindowHandle { /// A pointer to an orbclient window. // TODO(madsmtm): I think this is a file descriptor, so perhaps it should diff --git a/src/uikit.rs b/src/uikit.rs index 1f4895e..4a442b6 100644 --- a/src/uikit.rs +++ b/src/uikit.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for UIKit. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct UiKitDisplayHandle {} impl UiKitDisplayHandle { @@ -23,7 +23,7 @@ impl UiKitDisplayHandle { /// Raw window handle for UIKit. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct UiKitWindowHandle { /// A pointer to an `UIView` object. pub ui_view: NonNull, diff --git a/src/unix.rs b/src/unix.rs index e1d5023..246116d 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -4,7 +4,7 @@ use core::ptr::NonNull; /// Raw display handle for Xlib. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct XlibDisplayHandle { /// A pointer to an Xlib `Display`. /// @@ -44,7 +44,7 @@ impl XlibDisplayHandle { /// Raw window handle for Xlib. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct XlibWindowHandle { /// An Xlib `Window`. pub window: c_ulong, @@ -78,7 +78,7 @@ impl XlibWindowHandle { /// Raw display handle for Xcb. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct XcbDisplayHandle { /// A pointer to an X server `xcb_connection_t`. /// @@ -118,7 +118,7 @@ impl XcbDisplayHandle { /// Raw window handle for Xcb. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct XcbWindowHandle { /// An X11 `xcb_window_t`. pub window: NonZeroU32, // Based on xproto.h @@ -152,7 +152,7 @@ impl XcbWindowHandle { /// Raw display handle for Wayland. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct WaylandDisplayHandle { /// A pointer to a `wl_display`. pub display: NonNull, @@ -180,7 +180,7 @@ impl WaylandDisplayHandle { /// Raw window handle for Wayland. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct WaylandWindowHandle { /// A pointer to a `wl_surface`. pub surface: NonNull, @@ -208,7 +208,7 @@ impl WaylandWindowHandle { /// Raw display handle for the Linux Kernel Mode Set/Direct Rendering Manager. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct DrmDisplayHandle { /// The drm file descriptor. // TODO: Use `std::os::fd::RawFd`? @@ -235,7 +235,7 @@ impl DrmDisplayHandle { /// Raw window handle for the Linux Kernel Mode Set/Direct Rendering Manager. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct DrmWindowHandle { /// The primary drm plane handle. pub plane: u32, @@ -261,7 +261,7 @@ impl DrmWindowHandle { /// Raw display handle for the Linux Generic Buffer Manager. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct GbmDisplayHandle { /// The gbm device. pub gbm_device: NonNull, @@ -289,7 +289,7 @@ impl GbmDisplayHandle { /// Raw window handle for the Linux Generic Buffer Manager. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct GbmWindowHandle { /// The gbm surface. pub gbm_surface: NonNull, diff --git a/src/web.rs b/src/web.rs index 5bec0c0..4f23c07 100644 --- a/src/web.rs +++ b/src/web.rs @@ -1,6 +1,8 @@ +use core::fmt; + /// Raw display handle for the Web. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct WebDisplayHandle {} impl WebDisplayHandle { @@ -20,7 +22,7 @@ impl WebDisplayHandle { /// Raw window handle for the Web. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct WebWindowHandle { /// An ID value inserted into the [data attributes] of the canvas element as '`raw-handle`'. /// @@ -60,24 +62,21 @@ impl WebWindowHandle { /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct Wbg02CanvasWindowHandle { - /// The index of the canvas element in the [`wasm-bindgen`] table. + /// The object representing the [`HtmlCanvasElement`]. /// - /// If this index if non-zero, it is implied that it represents an [`HtmlCanvasElement`] - /// that is registered in the [`wasm-bindgen`] table. It can be converted to and from the - /// [`HtmlCanvasElement`] using [`wasm-bindgen`]'s [`FromWasmAbi`] and [`IntoWasmAbi`] traits. + /// It is implied that this object is registered in the [`wasm-bindgen`] table and is an instance + /// of [`HtmlCanvasElement`]. /// - /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html - /// [`FromWasmAbi`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.FromWasmAbi.html - /// [`IntoWasmAbi`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.IntoWasmAbi.html - pub idx: u32, + pub obj: Wbg02Object, } impl Wbg02CanvasWindowHandle { - pub fn empty() -> Self { - Self { idx: 0 } + /// Create a new handle to an [`HtmlCanvasElement`]. + pub fn new(obj: Wbg02Object) -> Self { + Self { obj } } } @@ -92,23 +91,89 @@ impl Wbg02CanvasWindowHandle { /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct Wbg02OffscreenCanvasWindowHandle { - /// The index of the canvas element in the [`wasm-bindgen`] table. + /// The object representing the [`OffscreenCanvas`]. /// - /// If this index if non-zero, it is implied that it represents an [`OffscreenCanvas`] - /// that is registered in the [`wasm-bindgen`] table. It can be converted to and from the - /// [`OffscreenCanvas`] using [`wasm-bindgen`]'s [`FromWasmAbi`] and [`IntoWasmAbi`] traits. + /// It is implied that this object is registered in the [`wasm-bindgen`] table and is an instance + /// of [`OffscreenCanvas`]. /// - /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html - /// [`FromWasmAbi`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.FromWasmAbi.html - /// [`IntoWasmAbi`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.IntoWasmAbi.html - pub idx: u32, + pub obj: Wbg02Object, } impl Wbg02OffscreenCanvasWindowHandle { - pub fn empty() -> Self { - Self { idx: 0 } + /// Create a new handle to an [`OffscreenCanvas`]. + pub fn new(obj: Wbg02Object) -> Self { + Self { obj } + } +} + +/// An object currently stored in [`wasm-bindgen`]. +/// +/// This type represents an object stored in the [`wasm-bindgen`] object table. It represents some kind +/// of underlying web object, such as an `HtmlCanvasElement` or an [`OffscreenCanvas`]. +/// +/// For WASM targets, with the unstable `unstable_web_handles` feature enabled, this type contains +/// an index into the table corresponding to a JavaScript object. In other cases, this type is +/// uninhabited. +/// +/// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen +/// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html +#[derive(Clone, PartialEq)] +pub struct Wbg02Object { + /// For when `unstable_web_handles` is enabled, this is the index of the object in the + /// `wasm-bindgen` table. + #[cfg(all(target_family = "wasm", feature = "unstable_web_handles"))] + idx: wasm_bindgen::JsValue, + + /// In other cases, this type is uninhabited. + #[cfg(not(all(target_family = "wasm", feature = "unstable_web_handles")))] + _uninhabited: core::convert::Infallible, +} + +impl fmt::Debug for Wbg02Object { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + #[cfg(all(target_family = "wasm", feature = "unstable_web_handles"))] + { + _f.debug_tuple("Wbg02Object").field(&self.idx).finish() + } + + #[cfg(not(all(target_family = "wasm", feature = "unstable_web_handles")))] + match self._uninhabited {} + } +} + +#[cfg(all(target_family = "wasm", feature = "unstable_web_handles"))] +/// These implementations are only available when `unstable_web_handles` is enabled. +impl Wbg02Object { + /// Create a new `Wbg02Object` from a [`wasm-bindgen`] object. + /// + /// This function is unstable. Its signature may be changed or even removed outright without a + /// breaking version change. + /// + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + pub fn new(idx: wasm_bindgen::JsValue) -> Self { + Self { idx } + } + + /// Get the index of the object in the [`wasm-bindgen`] table. + /// + /// This function is unstable. Its signature may be changed or even removed outright without a + /// breaking version change. + /// + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + pub fn idx(&self) -> &wasm_bindgen::JsValue { + &self.idx + } + + /// Convert to the underlying [`wasm-bindgen`] index. + /// + /// This function is unstable. Its signature may be changed or even removed outright without a + /// breaking version change. + /// + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + pub fn into_idx(self) -> wasm_bindgen::JsValue { + self.idx } } diff --git a/src/windows.rs b/src/windows.rs index 9751dbf..457639e 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -6,7 +6,7 @@ use core::ptr::NonNull; /// /// It can be used regardless of Windows window backend. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct WindowsDisplayHandle {} impl WindowsDisplayHandle { @@ -26,7 +26,7 @@ impl WindowsDisplayHandle { /// Raw window handle for Win32. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct Win32WindowHandle { /// A Win32 `HWND` handle. pub hwnd: NonZeroIsize, @@ -64,7 +64,7 @@ impl Win32WindowHandle { /// Raw window handle for WinRT. #[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub struct WinRtWindowHandle { /// A WinRT `CoreWindow` handle. pub core_window: NonNull, From 7179e66ffe3c54b2dc1292b24d5f8e44be249c74 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Fri, 1 Sep 2023 21:25:10 -0700 Subject: [PATCH 03/14] Fixup CI Signed-off-by: John Nunley --- .github/workflows/ci.yml | 16 ++++++---------- src/lib.rs | 3 ++- src/web.rs | 34 ++++++++++++++++++++++++++++------ 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c997113..d0fe180 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,19 +40,15 @@ jobs: with: rust-version: ${{ matrix.rust_version }} - - run: rustup target add x86_64-linux-android + - run: rustup target add wasm32-unknown-unknown - name: Check documentation run: cargo doc --no-deps --document-private-items - - name: Run tests - run: cargo test --verbose - - - name: Run tests with std - run: cargo test --verbose --features std + - run: taiki-e/install-action@cargo-hack - - name: Check on Android - run: cargo check --verbose --target x86_64-linux-android + - name: Run tests + run: cargo hack test --feature-powerset - - name: Check on Android with std - run: cargo check --verbose --target x86_64-linux-android --features std + - name: Run tests for wasm32-unknown-unknown + run: cargo hack check --target wasm32-unknown-unknown --feature-powerset diff --git a/src/lib.rs b/src/lib.rs index 9aa7bc9..fe280cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,7 +53,8 @@ pub use unix::{ WaylandWindowHandle, XcbDisplayHandle, XcbWindowHandle, XlibDisplayHandle, XlibWindowHandle, }; pub use web::{ - Wbg02CanvasWindowHandle, Wbg02OffscreenCanvasWindowHandle, WebDisplayHandle, WebWindowHandle, + Wbg02CanvasWindowHandle, Wbg02Object, Wbg02OffscreenCanvasWindowHandle, WebDisplayHandle, + WebWindowHandle, }; pub use windows::{Win32WindowHandle, WinRtWindowHandle, WindowsDisplayHandle}; diff --git a/src/web.rs b/src/web.rs index 4f23c07..0640d6b 100644 --- a/src/web.rs +++ b/src/web.rs @@ -54,9 +54,11 @@ impl WebWindowHandle { /// Raw window handle for a Web canvas registered via [`wasm-bindgen`]. /// /// ## Construction -/// ``` -/// # use raw_window_handle::Wbg02CanvasWindowHandle; -/// let mut window_handle = Wbg02CanvasWindowHandle::empty(); +/// ```no_run +/// # use raw_window_handle::{Wbg02CanvasWindowHandle, Wbg02Object}; +/// # fn get_canvas() -> Wbg02Object { unimplemented!() } +/// let obj: Wbg02Object = get_canvas(); +/// let mut window_handle = Wbg02CanvasWindowHandle::new(obj); /// /* set fields */ /// ``` /// @@ -70,11 +72,14 @@ pub struct Wbg02CanvasWindowHandle { /// of [`HtmlCanvasElement`]. /// /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen pub obj: Wbg02Object, } impl Wbg02CanvasWindowHandle { /// Create a new handle to an [`HtmlCanvasElement`]. + /// + /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html pub fn new(obj: Wbg02Object) -> Self { Self { obj } } @@ -83,9 +88,11 @@ impl Wbg02CanvasWindowHandle { /// Raw window handle for a Web offscreen canvas registered via [`wasm-bindgen`]. /// /// ## Construction -/// ``` -/// # use raw_window_handle::Wbg02OffscreenCanvasWindowHandle; -/// let mut window_handle = Wbg02OffscreenCanvasWindowHandle::empty(); +/// ```no_run +/// # use raw_window_handle::{Wbg02OffscreenCanvasWindowHandle, Wbg02Object}; +/// # fn get_offscreen_canvas() -> Wbg02Object { unimplemented!() } +/// let obj: Wbg02Object = get_offscreen_canvas(); +/// let mut window_handle = Wbg02OffscreenCanvasWindowHandle::new(obj); /// /* set fields */ /// ``` /// @@ -99,11 +106,14 @@ pub struct Wbg02OffscreenCanvasWindowHandle { /// of [`OffscreenCanvas`]. /// /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen pub obj: Wbg02Object, } impl Wbg02OffscreenCanvasWindowHandle { /// Create a new handle to an [`OffscreenCanvas`]. + /// + /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html pub fn new(obj: Wbg02Object) -> Self { Self { obj } } @@ -153,6 +163,10 @@ impl Wbg02Object { /// breaking version change. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + #[cfg_attr( + docsrs, + doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles"))) + )] pub fn new(idx: wasm_bindgen::JsValue) -> Self { Self { idx } } @@ -163,6 +177,10 @@ impl Wbg02Object { /// breaking version change. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + #[cfg_attr( + docsrs, + doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles"))) + )] pub fn idx(&self) -> &wasm_bindgen::JsValue { &self.idx } @@ -173,6 +191,10 @@ impl Wbg02Object { /// breaking version change. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + #[cfg_attr( + docsrs, + doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles"))) + )] pub fn into_idx(self) -> wasm_bindgen::JsValue { self.idx } From ec045e59742c634bc4ea0f735dd88c30969610ec Mon Sep 17 00:00:00 2001 From: John Nunley Date: Fri, 1 Sep 2023 21:26:07 -0700 Subject: [PATCH 04/14] Whoops Signed-off-by: John Nunley --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0fe180..36f629c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,7 +45,7 @@ jobs: - name: Check documentation run: cargo doc --no-deps --document-private-items - - run: taiki-e/install-action@cargo-hack + - uses: taiki-e/install-action@cargo-hack - name: Run tests run: cargo hack test --feature-powerset From a9fbe053b93a2301898dbacf1099626737b7da42 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sat, 2 Sep 2023 08:32:18 -0700 Subject: [PATCH 05/14] Rename feature to unstable_web_handles_wbg_02 Signed-off-by: John Nunley --- Cargo.toml | 2 +- src/web.rs | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5e4b923..f2dee2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ std = ["alloc"] # be removed entirely tomorrow. # # The point being: rely on this at your own peril. -unstable_web_handles = ["wasm-bindgen", "std"] +unstable_web_handles_wbg_02 = ["wasm-bindgen", "std"] [target.'cfg(target_family = "wasm")'.dependencies.wasm-bindgen] version = "0.2.87" diff --git a/src/web.rs b/src/web.rs index 0640d6b..6a27a9a 100644 --- a/src/web.rs +++ b/src/web.rs @@ -124,7 +124,7 @@ impl Wbg02OffscreenCanvasWindowHandle { /// This type represents an object stored in the [`wasm-bindgen`] object table. It represents some kind /// of underlying web object, such as an `HtmlCanvasElement` or an [`OffscreenCanvas`]. /// -/// For WASM targets, with the unstable `unstable_web_handles` feature enabled, this type contains +/// For WASM targets, with the unstable `unstable_web_handles_wbg_02` feature enabled, this type contains /// an index into the table corresponding to a JavaScript object. In other cases, this type is /// uninhabited. /// @@ -132,30 +132,30 @@ impl Wbg02OffscreenCanvasWindowHandle { /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html #[derive(Clone, PartialEq)] pub struct Wbg02Object { - /// For when `unstable_web_handles` is enabled, this is the index of the object in the + /// For when `unstable_web_handles_wbg_02` is enabled, this is the index of the object in the /// `wasm-bindgen` table. - #[cfg(all(target_family = "wasm", feature = "unstable_web_handles"))] + #[cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))] idx: wasm_bindgen::JsValue, /// In other cases, this type is uninhabited. - #[cfg(not(all(target_family = "wasm", feature = "unstable_web_handles")))] + #[cfg(not(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02")))] _uninhabited: core::convert::Infallible, } impl fmt::Debug for Wbg02Object { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(all(target_family = "wasm", feature = "unstable_web_handles"))] + #[cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))] { _f.debug_tuple("Wbg02Object").field(&self.idx).finish() } - #[cfg(not(all(target_family = "wasm", feature = "unstable_web_handles")))] + #[cfg(not(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02")))] match self._uninhabited {} } } -#[cfg(all(target_family = "wasm", feature = "unstable_web_handles"))] -/// These implementations are only available when `unstable_web_handles` is enabled. +#[cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))] +/// These implementations are only available when `unstable_web_handles_wbg_02` is enabled. impl Wbg02Object { /// Create a new `Wbg02Object` from a [`wasm-bindgen`] object. /// @@ -165,7 +165,7 @@ impl Wbg02Object { /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[cfg_attr( docsrs, - doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles"))) + doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) )] pub fn new(idx: wasm_bindgen::JsValue) -> Self { Self { idx } @@ -179,7 +179,7 @@ impl Wbg02Object { /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[cfg_attr( docsrs, - doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles"))) + doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) )] pub fn idx(&self) -> &wasm_bindgen::JsValue { &self.idx @@ -193,7 +193,7 @@ impl Wbg02Object { /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[cfg_attr( docsrs, - doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles"))) + doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) )] pub fn into_idx(self) -> wasm_bindgen::JsValue { self.idx From 4711c9547c794319189fa41ce708311cd24f5723 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sat, 2 Sep 2023 13:54:17 -0700 Subject: [PATCH 06/14] Use a raw pointer instead of the direct JsValue Signed-off-by: John Nunley --- src/lib.rs | 3 +- src/web.rs | 126 ++++++++++++++++++++++++++++------------------------- 2 files changed, 67 insertions(+), 62 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fe280cc..9aa7bc9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,8 +53,7 @@ pub use unix::{ WaylandWindowHandle, XcbDisplayHandle, XcbWindowHandle, XlibDisplayHandle, XlibWindowHandle, }; pub use web::{ - Wbg02CanvasWindowHandle, Wbg02Object, Wbg02OffscreenCanvasWindowHandle, WebDisplayHandle, - WebWindowHandle, + Wbg02CanvasWindowHandle, Wbg02OffscreenCanvasWindowHandle, WebDisplayHandle, WebWindowHandle, }; pub use windows::{Win32WindowHandle, WinRtWindowHandle, WindowsDisplayHandle}; diff --git a/src/web.rs b/src/web.rs index 6a27a9a..e7895c2 100644 --- a/src/web.rs +++ b/src/web.rs @@ -1,4 +1,5 @@ -use core::fmt; +use core::ffi::c_void; +use core::ptr::NonNull; /// Raw display handle for the Web. #[non_exhaustive] @@ -69,22 +70,65 @@ pub struct Wbg02CanvasWindowHandle { /// The object representing the [`HtmlCanvasElement`]. /// /// It is implied that this object is registered in the [`wasm-bindgen`] table and is an instance - /// of [`HtmlCanvasElement`]. + /// of [`HtmlCanvasElement`]. The pointer is a direct reference to a [`JsValue`]. /// /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen - pub obj: Wbg02Object, + /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html + pub obj: NonNull, } impl Wbg02CanvasWindowHandle { /// Create a new handle to an [`HtmlCanvasElement`]. /// /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html - pub fn new(obj: Wbg02Object) -> Self { + pub fn new(obj: NonNull) -> Self { Self { obj } } } +#[cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))] +/// These implementations are only available when `unstable_web_handles_wbg_02` is enabled. +impl Wbg02CanvasWindowHandle { + /// Create a new `Wbg02CanvasWindowHandle` from a [`wasm-bindgen`] object. + /// + /// This function is unstable. Its signature may be changed or even removed outright without a + /// breaking version change. + /// + /// # Safety + /// + /// The [`JsValue`] must refer to an [`HtmlCanvasElement`], and the lifetime must be longer than + /// the `Wbg02CanvasWindowHandle` lives for. + /// + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + #[cfg_attr( + docsrs, + doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) + )] + pub unsafe fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self { + Self::new(NonNull::from(js_value).cast()) + } + + /// Convert to the underlying [`wasm-bindgen`] index. + /// + /// This function is unstable. Its signature may be changed or even removed outright without a + /// breaking version change. + /// + /// # Safety + /// + /// The lifetime from the `from_wasm_bindgen_0_2` function must still be valid, and the + /// underlying pointer must still be a [`wasm_bindgen`] object. + /// + /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + #[cfg_attr( + docsrs, + doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) + )] + pub unsafe fn as_wasm_bindgen_0_2(&self) -> &wasm_bindgen::JsValue { + self.obj.cast().as_ref() + } +} + /// Raw window handle for a Web offscreen canvas registered via [`wasm-bindgen`]. /// /// ## Construction @@ -103,86 +147,43 @@ pub struct Wbg02OffscreenCanvasWindowHandle { /// The object representing the [`OffscreenCanvas`]. /// /// It is implied that this object is registered in the [`wasm-bindgen`] table and is an instance - /// of [`OffscreenCanvas`]. + /// of [`OffscreenCanvas`]. This is a pointer to the actual [`JsValue`] object. /// /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen - pub obj: Wbg02Object, + /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html + pub obj: NonNull, } impl Wbg02OffscreenCanvasWindowHandle { /// Create a new handle to an [`OffscreenCanvas`]. /// /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html - pub fn new(obj: Wbg02Object) -> Self { + pub fn new(obj: NonNull) -> Self { Self { obj } } } -/// An object currently stored in [`wasm-bindgen`]. -/// -/// This type represents an object stored in the [`wasm-bindgen`] object table. It represents some kind -/// of underlying web object, such as an `HtmlCanvasElement` or an [`OffscreenCanvas`]. -/// -/// For WASM targets, with the unstable `unstable_web_handles_wbg_02` feature enabled, this type contains -/// an index into the table corresponding to a JavaScript object. In other cases, this type is -/// uninhabited. -/// -/// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen -/// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html -#[derive(Clone, PartialEq)] -pub struct Wbg02Object { - /// For when `unstable_web_handles_wbg_02` is enabled, this is the index of the object in the - /// `wasm-bindgen` table. - #[cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))] - idx: wasm_bindgen::JsValue, - - /// In other cases, this type is uninhabited. - #[cfg(not(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02")))] - _uninhabited: core::convert::Infallible, -} - -impl fmt::Debug for Wbg02Object { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))] - { - _f.debug_tuple("Wbg02Object").field(&self.idx).finish() - } - - #[cfg(not(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02")))] - match self._uninhabited {} - } -} - #[cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))] /// These implementations are only available when `unstable_web_handles_wbg_02` is enabled. -impl Wbg02Object { - /// Create a new `Wbg02Object` from a [`wasm-bindgen`] object. +impl Wbg02OffscreenCanvasWindowHandle { + /// Create a new `Wbg02OffscreenCanvasWindowHandle` from a [`wasm-bindgen`] object. /// /// This function is unstable. Its signature may be changed or even removed outright without a /// breaking version change. /// - /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen - #[cfg_attr( - docsrs, - doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) - )] - pub fn new(idx: wasm_bindgen::JsValue) -> Self { - Self { idx } - } - - /// Get the index of the object in the [`wasm-bindgen`] table. + /// # Safety /// - /// This function is unstable. Its signature may be changed or even removed outright without a - /// breaking version change. + /// The [`JsValue`] must refer to an [`OffscreenCanvas`], and the lifetime must be longer than + /// the `Wbg02OffscreenCanvasWindowHandle` lives for. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[cfg_attr( docsrs, doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) )] - pub fn idx(&self) -> &wasm_bindgen::JsValue { - &self.idx + pub unsafe fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self { + Self::new(NonNull::from(js_value).cast()) } /// Convert to the underlying [`wasm-bindgen`] index. @@ -190,12 +191,17 @@ impl Wbg02Object { /// This function is unstable. Its signature may be changed or even removed outright without a /// breaking version change. /// + /// # Safety + /// + /// The lifetime from the `from_wasm_bindgen_0_2` function must still be valid, and the + /// underlying pointer must still be a [`wasm_bindgen`] object. + /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[cfg_attr( docsrs, doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) )] - pub fn into_idx(self) -> wasm_bindgen::JsValue { - self.idx + pub unsafe fn as_wasm_bindgen_0_2(&self) -> &wasm_bindgen::JsValue { + self.obj.cast().as_ref() } } From 62c92c28f804c8fd46640a03a7d98017a69e0f52 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sat, 2 Sep 2023 14:02:35 -0700 Subject: [PATCH 07/14] Fix CI issues Signed-off-by: John Nunley --- src/android.rs | 4 ++-- src/appkit.rs | 4 ++-- src/haiku.rs | 4 ++-- src/lib.rs | 4 ++-- src/redox.rs | 4 ++-- src/uikit.rs | 4 ++-- src/unix.rs | 20 ++++++++++---------- src/web.rs | 22 ++++++++++++---------- src/windows.rs | 6 +++--- 9 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/android.rs b/src/android.rs index 3afe70b..fc10ecb 100644 --- a/src/android.rs +++ b/src/android.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for Android. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct AndroidDisplayHandle {} impl AndroidDisplayHandle { @@ -23,7 +23,7 @@ impl AndroidDisplayHandle { /// Raw window handle for Android NDK. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct AndroidNdkWindowHandle { /// A pointer to an `ANativeWindow`. pub a_native_window: NonNull, diff --git a/src/appkit.rs b/src/appkit.rs index ec9a66c..3b05810 100644 --- a/src/appkit.rs +++ b/src/appkit.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for AppKit. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct AppKitDisplayHandle {} impl AppKitDisplayHandle { @@ -23,7 +23,7 @@ impl AppKitDisplayHandle { /// Raw window handle for AppKit. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct AppKitWindowHandle { /// A pointer to an `NSView` object. pub ns_view: NonNull, diff --git a/src/haiku.rs b/src/haiku.rs index f35696b..ef010ee 100644 --- a/src/haiku.rs +++ b/src/haiku.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for Haiku. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct HaikuDisplayHandle {} impl HaikuDisplayHandle { @@ -23,7 +23,7 @@ impl HaikuDisplayHandle { /// Raw window handle for Haiku. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct HaikuWindowHandle { /// A pointer to a BWindow object pub b_window: NonNull, diff --git a/src/lib.rs b/src/lib.rs index 9aa7bc9..60a36a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -123,7 +123,7 @@ unsafe impl HasRawWindowHandle for alloc::sync:: /// [`RawWindowHandle::Xlib`] on macOS, it would just be weird, and probably /// requires something like XQuartz be used). #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum RawWindowHandle { /// A raw window handle for UIKit (Apple's non-macOS windowing library). /// @@ -291,7 +291,7 @@ unsafe impl HasRawDisplayHandle for alloc::sync /// [`RawDisplayHandle::Xlib`] on macOS, it would just be weird, and probably /// requires something like XQuartz be used). #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum RawDisplayHandle { /// A raw display handle for UIKit (Apple's non-macOS windowing library). /// diff --git a/src/redox.rs b/src/redox.rs index 6a65977..7562756 100644 --- a/src/redox.rs +++ b/src/redox.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for the Redox operating system. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct OrbitalDisplayHandle {} impl OrbitalDisplayHandle { @@ -23,7 +23,7 @@ impl OrbitalDisplayHandle { /// Raw window handle for the Redox operating system. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct OrbitalWindowHandle { /// A pointer to an orbclient window. // TODO(madsmtm): I think this is a file descriptor, so perhaps it should diff --git a/src/uikit.rs b/src/uikit.rs index 4a442b6..1f4895e 100644 --- a/src/uikit.rs +++ b/src/uikit.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for UIKit. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct UiKitDisplayHandle {} impl UiKitDisplayHandle { @@ -23,7 +23,7 @@ impl UiKitDisplayHandle { /// Raw window handle for UIKit. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct UiKitWindowHandle { /// A pointer to an `UIView` object. pub ui_view: NonNull, diff --git a/src/unix.rs b/src/unix.rs index 246116d..e1d5023 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -4,7 +4,7 @@ use core::ptr::NonNull; /// Raw display handle for Xlib. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct XlibDisplayHandle { /// A pointer to an Xlib `Display`. /// @@ -44,7 +44,7 @@ impl XlibDisplayHandle { /// Raw window handle for Xlib. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct XlibWindowHandle { /// An Xlib `Window`. pub window: c_ulong, @@ -78,7 +78,7 @@ impl XlibWindowHandle { /// Raw display handle for Xcb. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct XcbDisplayHandle { /// A pointer to an X server `xcb_connection_t`. /// @@ -118,7 +118,7 @@ impl XcbDisplayHandle { /// Raw window handle for Xcb. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct XcbWindowHandle { /// An X11 `xcb_window_t`. pub window: NonZeroU32, // Based on xproto.h @@ -152,7 +152,7 @@ impl XcbWindowHandle { /// Raw display handle for Wayland. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct WaylandDisplayHandle { /// A pointer to a `wl_display`. pub display: NonNull, @@ -180,7 +180,7 @@ impl WaylandDisplayHandle { /// Raw window handle for Wayland. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct WaylandWindowHandle { /// A pointer to a `wl_surface`. pub surface: NonNull, @@ -208,7 +208,7 @@ impl WaylandWindowHandle { /// Raw display handle for the Linux Kernel Mode Set/Direct Rendering Manager. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct DrmDisplayHandle { /// The drm file descriptor. // TODO: Use `std::os::fd::RawFd`? @@ -235,7 +235,7 @@ impl DrmDisplayHandle { /// Raw window handle for the Linux Kernel Mode Set/Direct Rendering Manager. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct DrmWindowHandle { /// The primary drm plane handle. pub plane: u32, @@ -261,7 +261,7 @@ impl DrmWindowHandle { /// Raw display handle for the Linux Generic Buffer Manager. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct GbmDisplayHandle { /// The gbm device. pub gbm_device: NonNull, @@ -289,7 +289,7 @@ impl GbmDisplayHandle { /// Raw window handle for the Linux Generic Buffer Manager. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct GbmWindowHandle { /// The gbm surface. pub gbm_surface: NonNull, diff --git a/src/web.rs b/src/web.rs index e7895c2..da65980 100644 --- a/src/web.rs +++ b/src/web.rs @@ -3,7 +3,7 @@ use core::ptr::NonNull; /// Raw display handle for the Web. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct WebDisplayHandle {} impl WebDisplayHandle { @@ -23,7 +23,7 @@ impl WebDisplayHandle { /// Raw window handle for the Web. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct WebWindowHandle { /// An ID value inserted into the [data attributes] of the canvas element as '`raw-handle`'. /// @@ -56,16 +56,17 @@ impl WebWindowHandle { /// /// ## Construction /// ```no_run -/// # use raw_window_handle::{Wbg02CanvasWindowHandle, Wbg02Object}; -/// # fn get_canvas() -> Wbg02Object { unimplemented!() } -/// let obj: Wbg02Object = get_canvas(); +/// # use raw_window_handle::Wbg02CanvasWindowHandle; +/// # use core::{ffi::c_void, ptr::NonNull}; +/// # fn get_canvas() -> NonNull { unimplemented!() } +/// let obj: NonNull = get_canvas(); /// let mut window_handle = Wbg02CanvasWindowHandle::new(obj); /// /* set fields */ /// ``` /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Wbg02CanvasWindowHandle { /// The object representing the [`HtmlCanvasElement`]. /// @@ -133,16 +134,17 @@ impl Wbg02CanvasWindowHandle { /// /// ## Construction /// ```no_run -/// # use raw_window_handle::{Wbg02OffscreenCanvasWindowHandle, Wbg02Object}; -/// # fn get_offscreen_canvas() -> Wbg02Object { unimplemented!() } -/// let obj: Wbg02Object = get_offscreen_canvas(); +/// # use raw_window_handle::Wbg02OffscreenCanvasWindowHandle; +/// # use core::{ffi::c_void, ptr::NonNull}; +/// # fn get_offscreen_canvas() -> NonNull { unimplemented!() } +/// let obj: NonNull = get_offscreen_canvas(); /// let mut window_handle = Wbg02OffscreenCanvasWindowHandle::new(obj); /// /* set fields */ /// ``` /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Wbg02OffscreenCanvasWindowHandle { /// The object representing the [`OffscreenCanvas`]. /// diff --git a/src/windows.rs b/src/windows.rs index 457639e..9751dbf 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -6,7 +6,7 @@ use core::ptr::NonNull; /// /// It can be used regardless of Windows window backend. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct WindowsDisplayHandle {} impl WindowsDisplayHandle { @@ -26,7 +26,7 @@ impl WindowsDisplayHandle { /// Raw window handle for Win32. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Win32WindowHandle { /// A Win32 `HWND` handle. pub hwnd: NonZeroIsize, @@ -64,7 +64,7 @@ impl Win32WindowHandle { /// Raw window handle for WinRT. #[non_exhaustive] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct WinRtWindowHandle { /// A WinRT `CoreWindow` handle. pub core_window: NonNull, From a36375995fbb2714acf5c6dd0defeb0ef6c8a49e Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sat, 2 Sep 2023 15:33:07 -0700 Subject: [PATCH 08/14] Review comments Signed-off-by: John Nunley --- src/borrowed.rs | 8 ++--- src/web.rs | 92 +++++++++++++++++++++---------------------------- 2 files changed, 43 insertions(+), 57 deletions(-) diff --git a/src/borrowed.rs b/src/borrowed.rs index 3c2fd91..85b3b58 100644 --- a/src/borrowed.rs +++ b/src/borrowed.rs @@ -84,7 +84,7 @@ impl HasDisplayHandle for alloc::sync::Arc { /// /// Get the underlying raw display handle with the [`HasRawDisplayHandle`] trait. #[repr(transparent)] -#[derive(PartialEq, Clone)] +#[derive(PartialEq, Eq, Hash, Clone)] pub struct DisplayHandle<'a> { raw: RawDisplayHandle, _marker: PhantomData<&'a *const ()>, @@ -112,7 +112,7 @@ impl<'a> DisplayHandle<'a> { unsafe impl HasRawDisplayHandle for DisplayHandle<'_> { fn raw_display_handle(&self) -> Result { - Ok(self.raw.clone()) + Ok(self.raw) } } @@ -209,7 +209,7 @@ impl HasWindowHandle for alloc::sync::Arc { /// /// This handle is guaranteed to be safe and valid. Get the underlying raw window handle with the /// [`HasRawWindowHandle`] trait. -#[derive(PartialEq, Clone)] +#[derive(PartialEq, Eq, Hash, Clone)] pub struct WindowHandle<'a> { raw: RawWindowHandle, _marker: PhantomData<&'a *const ()>, @@ -237,7 +237,7 @@ impl<'a> WindowHandle<'a> { unsafe impl HasRawWindowHandle for WindowHandle<'_> { fn raw_window_handle(&self) -> Result { - Ok(self.raw.clone()) + Ok(self.raw) } } diff --git a/src/web.rs b/src/web.rs index da65980..ea51e18 100644 --- a/src/web.rs +++ b/src/web.rs @@ -54,24 +54,11 @@ impl WebWindowHandle { /// Raw window handle for a Web canvas registered via [`wasm-bindgen`]. /// -/// ## Construction -/// ```no_run -/// # use raw_window_handle::Wbg02CanvasWindowHandle; -/// # use core::{ffi::c_void, ptr::NonNull}; -/// # fn get_canvas() -> NonNull { unimplemented!() } -/// let obj: NonNull = get_canvas(); -/// let mut window_handle = Wbg02CanvasWindowHandle::new(obj); -/// /* set fields */ -/// ``` -/// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[non_exhaustive] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Wbg02CanvasWindowHandle { - /// The object representing the [`HtmlCanvasElement`]. - /// - /// It is implied that this object is registered in the [`wasm-bindgen`] table and is an instance - /// of [`HtmlCanvasElement`]. The pointer is a direct reference to a [`JsValue`]. + /// The pointer to the [`JsValue`] of an [`HtmlCanvasElement`]. /// /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen @@ -80,16 +67,30 @@ pub struct Wbg02CanvasWindowHandle { } impl Wbg02CanvasWindowHandle { - /// Create a new handle to an [`HtmlCanvasElement`]. + /// Create a new handle to a pointer to [`HtmlCanvasElement`]. /// /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html + /// + /// ## Example + /// ```no_run + /// # use raw_window_handle::Wbg02CanvasWindowHandle; + /// # use core::{ffi::c_void, ptr::NonNull}; + /// # fn get_canvas() -> NonNull { unimplemented!() } + /// let obj: NonNull = get_canvas(); + /// let mut window_handle = Wbg02CanvasWindowHandle::new(obj); + /// /* set fields */ + /// ``` pub fn new(obj: NonNull) -> Self { Self { obj } } } -#[cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))] -/// These implementations are only available when `unstable_web_handles_wbg_02` is enabled. +#[cfg(all(target_family = "wasm", feature = "unstable-wasm-bindgen-0-2"))] +#[cfg_attr( + docsrs, + doc(cfg(all(target_family = "wasm", feature = "unstable-wasm-bindgen-0-2"))) +)] +/// These implementations are only available when `unstable-wasm-bindgen-0-2` is enabled. impl Wbg02CanvasWindowHandle { /// Create a new `Wbg02CanvasWindowHandle` from a [`wasm-bindgen`] object. /// @@ -102,11 +103,7 @@ impl Wbg02CanvasWindowHandle { /// the `Wbg02CanvasWindowHandle` lives for. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen - #[cfg_attr( - docsrs, - doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) - )] - pub unsafe fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self { + pub fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self { Self::new(NonNull::from(js_value).cast()) } @@ -121,10 +118,6 @@ impl Wbg02CanvasWindowHandle { /// underlying pointer must still be a [`wasm_bindgen`] object. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen - #[cfg_attr( - docsrs, - doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) - )] pub unsafe fn as_wasm_bindgen_0_2(&self) -> &wasm_bindgen::JsValue { self.obj.cast().as_ref() } @@ -132,33 +125,30 @@ impl Wbg02CanvasWindowHandle { /// Raw window handle for a Web offscreen canvas registered via [`wasm-bindgen`]. /// -/// ## Construction -/// ```no_run -/// # use raw_window_handle::Wbg02OffscreenCanvasWindowHandle; -/// # use core::{ffi::c_void, ptr::NonNull}; -/// # fn get_offscreen_canvas() -> NonNull { unimplemented!() } -/// let obj: NonNull = get_offscreen_canvas(); -/// let mut window_handle = Wbg02OffscreenCanvasWindowHandle::new(obj); -/// /* set fields */ -/// ``` -/// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[non_exhaustive] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Wbg02OffscreenCanvasWindowHandle { - /// The object representing the [`OffscreenCanvas`]. - /// - /// It is implied that this object is registered in the [`wasm-bindgen`] table and is an instance - /// of [`OffscreenCanvas`]. This is a pointer to the actual [`JsValue`] object. + /// The pointer to the [`JsValue`] of an [`OffscreenElement`]. /// - /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html + /// [`OffscreenElement`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenElement.html /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html pub obj: NonNull, } impl Wbg02OffscreenCanvasWindowHandle { - /// Create a new handle to an [`OffscreenCanvas`]. + /// Create a new handle to a pointer to an [`OffscreenCanvas`]. + /// + /// ## Construction + /// ```no_run + /// # use raw_window_handle::Wbg02OffscreenCanvasWindowHandle; + /// # use core::{ffi::c_void, ptr::NonNull}; + /// # fn get_offscreen_canvas() -> NonNull { unimplemented!() } + /// let obj: NonNull = get_offscreen_canvas(); + /// let mut window_handle = Wbg02OffscreenCanvasWindowHandle::new(obj); + /// /* set fields */ + /// ``` /// /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html pub fn new(obj: NonNull) -> Self { @@ -166,8 +156,12 @@ impl Wbg02OffscreenCanvasWindowHandle { } } -#[cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))] -/// These implementations are only available when `unstable_web_handles_wbg_02` is enabled. +#[cfg(all(target_family = "wasm", feature = "unstable-wasm-bindgen-0-2"))] +#[cfg_attr( + docsrs, + doc(cfg(all(target_family = "wasm", feature = "unstable-wasm-bindgen-0-2"))) +)] +/// These implementations are only available when `unstable-wasm-bindgen-0-2` is enabled. impl Wbg02OffscreenCanvasWindowHandle { /// Create a new `Wbg02OffscreenCanvasWindowHandle` from a [`wasm-bindgen`] object. /// @@ -180,11 +174,7 @@ impl Wbg02OffscreenCanvasWindowHandle { /// the `Wbg02OffscreenCanvasWindowHandle` lives for. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen - #[cfg_attr( - docsrs, - doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) - )] - pub unsafe fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self { + pub fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self { Self::new(NonNull::from(js_value).cast()) } @@ -199,10 +189,6 @@ impl Wbg02OffscreenCanvasWindowHandle { /// underlying pointer must still be a [`wasm_bindgen`] object. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen - #[cfg_attr( - docsrs, - doc(cfg(all(target_family = "wasm", feature = "unstable_web_handles_wbg_02"))) - )] pub unsafe fn as_wasm_bindgen_0_2(&self) -> &wasm_bindgen::JsValue { self.obj.cast().as_ref() } From f8b3f9d057250bf7e7b42cc8880eaae6cb93f77f Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 3 Sep 2023 01:08:28 +0200 Subject: [PATCH 09/14] Fix wasm feature name and structs names --- Cargo.toml | 10 ++-------- src/lib.rs | 6 +++--- src/web.rs | 32 ++++++++++++++++---------------- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f2dee2e..a13cf13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,14 +15,8 @@ rust-version = "1.64" alloc = [] std = ["alloc"] -# Unstable feature to allow the use of `wasm-bindgen` in the `wasm` target. -# -# This is radioactive semver-wise. Do not rely on this in stable code. Any code enabled by this -# feature can be changed or removed in a breaking way at any time. In fact, this feature could -# be removed entirely tomorrow. -# -# The point being: rely on this at your own peril. -unstable_web_handles_wbg_02 = ["wasm-bindgen", "std"] +# Allow conversion methods to/from WASM types using `wasm-bindgen` v0.2. +wasm-bindgen-0-2 = ["wasm-bindgen", "std"] [target.'cfg(target_family = "wasm")'.dependencies.wasm-bindgen] version = "0.2.87" diff --git a/src/lib.rs b/src/lib.rs index 60a36a5..4ee4a0a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,7 +53,7 @@ pub use unix::{ WaylandWindowHandle, XcbDisplayHandle, XcbWindowHandle, XlibDisplayHandle, XlibWindowHandle, }; pub use web::{ - Wbg02CanvasWindowHandle, Wbg02OffscreenCanvasWindowHandle, WebDisplayHandle, WebWindowHandle, + WebCanvasWindowHandle, WebDisplayHandle, WebOffscreenCanvasWindowHandle, WebWindowHandle, }; pub use windows::{Win32WindowHandle, WinRtWindowHandle, WindowsDisplayHandle}; @@ -198,14 +198,14 @@ pub enum RawWindowHandle { /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen - Wgb02Canvas(Wbg02CanvasWindowHandle), + WebCanvas(WebCanvasWindowHandle), /// A raw window handle for a Web offscreen canvas registered via [`wasm-bindgen`]. /// /// ## Availability Hints /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen - Wgb02OffscreenCanvas(Wbg02OffscreenCanvasWindowHandle), + WebOffscreenCanvas(WebOffscreenCanvasWindowHandle), /// A raw window handle for Android NDK. /// /// ## Availability Hints diff --git a/src/web.rs b/src/web.rs index ea51e18..530c0e8 100644 --- a/src/web.rs +++ b/src/web.rs @@ -57,7 +57,7 @@ impl WebWindowHandle { /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[non_exhaustive] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Wbg02CanvasWindowHandle { +pub struct WebCanvasWindowHandle { /// The pointer to the [`JsValue`] of an [`HtmlCanvasElement`]. /// /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html @@ -66,18 +66,18 @@ pub struct Wbg02CanvasWindowHandle { pub obj: NonNull, } -impl Wbg02CanvasWindowHandle { +impl WebCanvasWindowHandle { /// Create a new handle to a pointer to [`HtmlCanvasElement`]. /// /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html /// /// ## Example /// ```no_run - /// # use raw_window_handle::Wbg02CanvasWindowHandle; + /// # use raw_window_handle::WebCanvasWindowHandle; /// # use core::{ffi::c_void, ptr::NonNull}; /// # fn get_canvas() -> NonNull { unimplemented!() } /// let obj: NonNull = get_canvas(); - /// let mut window_handle = Wbg02CanvasWindowHandle::new(obj); + /// let mut window_handle = WebCanvasWindowHandle::new(obj); /// /* set fields */ /// ``` pub fn new(obj: NonNull) -> Self { @@ -85,13 +85,13 @@ impl Wbg02CanvasWindowHandle { } } -#[cfg(all(target_family = "wasm", feature = "unstable-wasm-bindgen-0-2"))] +#[cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2"))] #[cfg_attr( docsrs, - doc(cfg(all(target_family = "wasm", feature = "unstable-wasm-bindgen-0-2"))) + doc(cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2"))) )] -/// These implementations are only available when `unstable-wasm-bindgen-0-2` is enabled. -impl Wbg02CanvasWindowHandle { +/// These implementations are only available when `wasm-bindgen-0-2` is enabled. +impl WebCanvasWindowHandle { /// Create a new `Wbg02CanvasWindowHandle` from a [`wasm-bindgen`] object. /// /// This function is unstable. Its signature may be changed or even removed outright without a @@ -128,7 +128,7 @@ impl Wbg02CanvasWindowHandle { /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[non_exhaustive] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Wbg02OffscreenCanvasWindowHandle { +pub struct WebOffscreenCanvasWindowHandle { /// The pointer to the [`JsValue`] of an [`OffscreenElement`]. /// /// [`OffscreenElement`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenElement.html @@ -137,16 +137,16 @@ pub struct Wbg02OffscreenCanvasWindowHandle { pub obj: NonNull, } -impl Wbg02OffscreenCanvasWindowHandle { +impl WebOffscreenCanvasWindowHandle { /// Create a new handle to a pointer to an [`OffscreenCanvas`]. /// /// ## Construction /// ```no_run - /// # use raw_window_handle::Wbg02OffscreenCanvasWindowHandle; + /// # use raw_window_handle::WebOffscreenCanvasWindowHandle; /// # use core::{ffi::c_void, ptr::NonNull}; /// # fn get_offscreen_canvas() -> NonNull { unimplemented!() } /// let obj: NonNull = get_offscreen_canvas(); - /// let mut window_handle = Wbg02OffscreenCanvasWindowHandle::new(obj); + /// let mut window_handle = WebOffscreenCanvasWindowHandle::new(obj); /// /* set fields */ /// ``` /// @@ -156,13 +156,13 @@ impl Wbg02OffscreenCanvasWindowHandle { } } -#[cfg(all(target_family = "wasm", feature = "unstable-wasm-bindgen-0-2"))] +#[cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2"))] #[cfg_attr( docsrs, - doc(cfg(all(target_family = "wasm", feature = "unstable-wasm-bindgen-0-2"))) + doc(cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2"))) )] -/// These implementations are only available when `unstable-wasm-bindgen-0-2` is enabled. -impl Wbg02OffscreenCanvasWindowHandle { +/// These implementations are only available when `wasm-bindgen-0-2` is enabled. +impl WebOffscreenCanvasWindowHandle { /// Create a new `Wbg02OffscreenCanvasWindowHandle` from a [`wasm-bindgen`] object. /// /// This function is unstable. Its signature may be changed or even removed outright without a From 4dd1c613cb77f13efbac00f8f5ebc1b29564e24f Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 3 Sep 2023 01:12:24 +0200 Subject: [PATCH 10/14] Re-add Copy --- src/borrowed.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/borrowed.rs b/src/borrowed.rs index 85b3b58..9ee9d58 100644 --- a/src/borrowed.rs +++ b/src/borrowed.rs @@ -84,7 +84,7 @@ impl HasDisplayHandle for alloc::sync::Arc { /// /// Get the underlying raw display handle with the [`HasRawDisplayHandle`] trait. #[repr(transparent)] -#[derive(PartialEq, Eq, Hash, Clone)] +#[derive(PartialEq, Eq, Hash, Copy, Clone)] pub struct DisplayHandle<'a> { raw: RawDisplayHandle, _marker: PhantomData<&'a *const ()>, @@ -118,7 +118,7 @@ unsafe impl HasRawDisplayHandle for DisplayHandle<'_> { impl<'a> HasDisplayHandle for DisplayHandle<'a> { fn display_handle(&self) -> Result, HandleError> { - Ok(self.clone()) + Ok(*self) } } @@ -209,7 +209,7 @@ impl HasWindowHandle for alloc::sync::Arc { /// /// This handle is guaranteed to be safe and valid. Get the underlying raw window handle with the /// [`HasRawWindowHandle`] trait. -#[derive(PartialEq, Eq, Hash, Clone)] +#[derive(PartialEq, Eq, Hash, Copy, Clone)] pub struct WindowHandle<'a> { raw: RawWindowHandle, _marker: PhantomData<&'a *const ()>, @@ -243,7 +243,7 @@ unsafe impl HasRawWindowHandle for WindowHandle<'_> { impl HasWindowHandle for WindowHandle<'_> { fn window_handle(&self) -> Result { - Ok(self.clone()) + Ok(*self) } } From 8c15e15f9537bbd8b8e23282e7a1bb3ae9d4bf95 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 3 Sep 2023 01:14:45 +0200 Subject: [PATCH 11/14] Redo web canvas examples --- src/web.rs | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/web.rs b/src/web.rs index 530c0e8..b53a6be 100644 --- a/src/web.rs +++ b/src/web.rs @@ -71,14 +71,19 @@ impl WebCanvasWindowHandle { /// /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html /// - /// ## Example - /// ```no_run + /// # Example + /// + /// ``` + /// # use core::ffi::c_void; + /// # use core::ptr::NonNull; /// # use raw_window_handle::WebCanvasWindowHandle; - /// # use core::{ffi::c_void, ptr::NonNull}; - /// # fn get_canvas() -> NonNull { unimplemented!() } - /// let obj: NonNull = get_canvas(); - /// let mut window_handle = WebCanvasWindowHandle::new(obj); - /// /* set fields */ + /// # type HtmlCanvasElement = (); + /// # type JsValue = (); + /// let canvas: &HtmlCanvasElement; + /// # canvas = &(); + /// let value: &JsValue = &canvas; // Deref to `JsValue` + /// let obj: NonNull = NonNull::from(value).cast(); + /// let mut handle = WebCanvasWindowHandle::new(obj); /// ``` pub fn new(obj: NonNull) -> Self { Self { obj } @@ -140,17 +145,22 @@ pub struct WebOffscreenCanvasWindowHandle { impl WebOffscreenCanvasWindowHandle { /// Create a new handle to a pointer to an [`OffscreenCanvas`]. /// - /// ## Construction - /// ```no_run + /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html + /// + /// # Example + /// + /// ``` + /// # use core::ffi::c_void; + /// # use core::ptr::NonNull; /// # use raw_window_handle::WebOffscreenCanvasWindowHandle; - /// # use core::{ffi::c_void, ptr::NonNull}; - /// # fn get_offscreen_canvas() -> NonNull { unimplemented!() } - /// let obj: NonNull = get_offscreen_canvas(); - /// let mut window_handle = WebOffscreenCanvasWindowHandle::new(obj); - /// /* set fields */ + /// # type OffscreenCanvas = (); + /// # type JsValue = (); + /// let canvas: &OffscreenCanvas; + /// # canvas = &(); + /// let value: &JsValue = &canvas; // Deref to `JsValue` + /// let obj: NonNull = NonNull::from(value).cast(); + /// let mut handle = WebOffscreenCanvasWindowHandle::new(obj); /// ``` - /// - /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html pub fn new(obj: NonNull) -> Self { Self { obj } } From 789b26a4e579a4395f7555b23a52e3010a8b15cf Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 3 Sep 2023 01:25:57 +0200 Subject: [PATCH 12/14] Documentation tweaks --- src/lib.rs | 1 + src/web.rs | 70 ++++++++++++++++++------------------------------------ 2 files changed, 24 insertions(+), 47 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4ee4a0a..f746967 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![allow(clippy::new_without_default)] +#![deny(unsafe_op_in_unsafe_fn)] //! Interoperability library for Rust Windowing applications. //! diff --git a/src/web.rs b/src/web.rs index b53a6be..a6b5838 100644 --- a/src/web.rs +++ b/src/web.rs @@ -58,16 +58,15 @@ impl WebWindowHandle { #[non_exhaustive] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct WebCanvasWindowHandle { - /// The pointer to the [`JsValue`] of an [`HtmlCanvasElement`]. + /// A pointer to the [`JsValue`] of an [`HtmlCanvasElement`]. /// - /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html - /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html + /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html pub obj: NonNull, } impl WebCanvasWindowHandle { - /// Create a new handle to a pointer to [`HtmlCanvasElement`]. + /// Create a new handle from a pointer to [`HtmlCanvasElement`]. /// /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html /// @@ -97,53 +96,41 @@ impl WebCanvasWindowHandle { )] /// These implementations are only available when `wasm-bindgen-0-2` is enabled. impl WebCanvasWindowHandle { - /// Create a new `Wbg02CanvasWindowHandle` from a [`wasm-bindgen`] object. - /// - /// This function is unstable. Its signature may be changed or even removed outright without a - /// breaking version change. - /// - /// # Safety - /// - /// The [`JsValue`] must refer to an [`HtmlCanvasElement`], and the lifetime must be longer than - /// the `Wbg02CanvasWindowHandle` lives for. + /// Create a new `WebCanvasWindowHandle` from a [`wasm_bindgen::JsValue`]. /// - /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + /// The `JsValue` should refer to a `HtmlCanvasElement`, and the lifetime + /// of the value should be at least as long as the lifetime of this. pub fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self { Self::new(NonNull::from(js_value).cast()) } - /// Convert to the underlying [`wasm-bindgen`] index. - /// - /// This function is unstable. Its signature may be changed or even removed outright without a - /// breaking version change. + /// Convert to the underlying [`wasm_bindgen::JsValue`]. /// /// # Safety /// - /// The lifetime from the `from_wasm_bindgen_0_2` function must still be valid, and the - /// underlying pointer must still be a [`wasm_bindgen`] object. - /// - /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + /// The inner pointer must be valid. This is ensured if this handle was + /// borrowed from [`WindowHandle`][crate::WindowHandle]. pub unsafe fn as_wasm_bindgen_0_2(&self) -> &wasm_bindgen::JsValue { - self.obj.cast().as_ref() + unsafe { self.obj.cast().as_ref() } } } -/// Raw window handle for a Web offscreen canvas registered via [`wasm-bindgen`]. +/// Raw window handle for a Web offscreen canvas registered via +/// [`wasm-bindgen`]. /// /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen #[non_exhaustive] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct WebOffscreenCanvasWindowHandle { - /// The pointer to the [`JsValue`] of an [`OffscreenElement`]. + /// A pointer to the [`JsValue`] of an [`OffscreenCanvas`]. /// - /// [`OffscreenElement`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenElement.html - /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html + /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html pub obj: NonNull, } impl WebOffscreenCanvasWindowHandle { - /// Create a new handle to a pointer to an [`OffscreenCanvas`]. + /// Create a new handle from a pointer to an [`OffscreenCanvas`]. /// /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html /// @@ -173,33 +160,22 @@ impl WebOffscreenCanvasWindowHandle { )] /// These implementations are only available when `wasm-bindgen-0-2` is enabled. impl WebOffscreenCanvasWindowHandle { - /// Create a new `Wbg02OffscreenCanvasWindowHandle` from a [`wasm-bindgen`] object. - /// - /// This function is unstable. Its signature may be changed or even removed outright without a - /// breaking version change. - /// - /// # Safety + /// Create a new `WebOffscreenCanvasWindowHandle` from a + /// [`wasm_bindgen::JsValue`]. /// - /// The [`JsValue`] must refer to an [`OffscreenCanvas`], and the lifetime must be longer than - /// the `Wbg02OffscreenCanvasWindowHandle` lives for. - /// - /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + /// The `JsValue` should refer to a `HtmlCanvasElement`, and the lifetime + /// of the value should be at least as long as the lifetime of this. pub fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self { Self::new(NonNull::from(js_value).cast()) } - /// Convert to the underlying [`wasm-bindgen`] index. - /// - /// This function is unstable. Its signature may be changed or even removed outright without a - /// breaking version change. + /// Convert to the underlying [`wasm_bindgen::JsValue`]. /// /// # Safety /// - /// The lifetime from the `from_wasm_bindgen_0_2` function must still be valid, and the - /// underlying pointer must still be a [`wasm_bindgen`] object. - /// - /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen + /// The inner pointer must be valid. This is ensured if this handle was + /// borrowed from [`WindowHandle`][crate::WindowHandle]. pub unsafe fn as_wasm_bindgen_0_2(&self) -> &wasm_bindgen::JsValue { - self.obj.cast().as_ref() + unsafe { self.obj.cast().as_ref() } } } From a79764c3330f8cca77e4cee90270255d3ee6f2a4 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 3 Sep 2023 01:38:57 +0200 Subject: [PATCH 13/14] Add safety comment about ABI --- src/web.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/web.rs b/src/web.rs index a6b5838..9e782a8 100644 --- a/src/web.rs +++ b/src/web.rs @@ -60,8 +60,19 @@ impl WebWindowHandle { pub struct WebCanvasWindowHandle { /// A pointer to the [`JsValue`] of an [`HtmlCanvasElement`]. /// + /// Note: This uses [`c_void`] to avoid depending on `wasm-bindgen` + /// directly. + /// /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html + // + // SAFETY: Not using `JsValue` is sound because `wasm-bindgen` guarantees + // that there's only one version of itself in any given binary, and hence + // we can't have a type-confusion where e.g. one library used `JsValue` + // from `v0.2` of `wasm-bindgen`, and another used `JsValue` from `v1.0`; + // the binary will simply fail to compile! + // + // Reference: TODO pub obj: NonNull, } @@ -124,8 +135,13 @@ impl WebCanvasWindowHandle { pub struct WebOffscreenCanvasWindowHandle { /// A pointer to the [`JsValue`] of an [`OffscreenCanvas`]. /// + /// Note: This uses [`c_void`] to avoid depending on `wasm-bindgen` + /// directly. + /// /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html + // + // SAFETY: See WebCanvasWindowHandle. pub obj: NonNull, } From 23d2195626ee65c1b8d86da5ba1919a044e05f49 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 3 Sep 2023 02:31:19 +0200 Subject: [PATCH 14/14] Add From impls for the new web handles --- src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index f746967..4bf6912 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -449,5 +449,11 @@ from_impl!(RawWindowHandle, Gbm, GbmWindowHandle); from_impl!(RawWindowHandle, Win32, Win32WindowHandle); from_impl!(RawWindowHandle, WinRt, WinRtWindowHandle); from_impl!(RawWindowHandle, Web, WebWindowHandle); +from_impl!(RawWindowHandle, WebCanvas, WebCanvasWindowHandle); +from_impl!( + RawWindowHandle, + WebOffscreenCanvas, + WebOffscreenCanvasWindowHandle +); from_impl!(RawWindowHandle, AndroidNdk, AndroidNdkWindowHandle); from_impl!(RawWindowHandle, Haiku, HaikuWindowHandle);