raw_window_handle/
web.rs

1use core::ffi::c_void;
2use core::ptr::NonNull;
3
4use super::DisplayHandle;
5
6/// Raw display handle for the Web.
7#[non_exhaustive]
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub struct WebDisplayHandle {}
10
11impl WebDisplayHandle {
12    /// Create a new empty display handle.
13    ///
14    ///
15    /// # Example
16    ///
17    /// ```
18    /// # use raw_window_handle::WebDisplayHandle;
19    /// let handle = WebDisplayHandle::new();
20    /// ```
21    pub fn new() -> Self {
22        Self {}
23    }
24}
25
26impl DisplayHandle<'static> {
27    /// Create a Web-based display handle.
28    ///
29    /// As no data is borrowed by this handle, it is completely safe to create. This function
30    /// may be useful to windowing framework implementations that want to avoid unsafe code.
31    ///
32    /// # Example
33    ///
34    /// ```
35    /// # use raw_window_handle::{DisplayHandle, HasDisplayHandle};
36    /// # fn do_something(rwh: impl HasDisplayHandle) { let _ = rwh; }
37    /// let handle = DisplayHandle::web();
38    /// do_something(handle);
39    /// ```
40    pub fn web() -> Self {
41        // SAFETY: No data is borrowed.
42        unsafe { Self::borrow_raw(WebDisplayHandle::new().into()) }
43    }
44}
45
46/// Raw window handle for the Web.
47#[non_exhaustive]
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
49pub struct WebWindowHandle {
50    /// An ID value inserted into the [data attributes] of the canvas element as '`raw-handle`'.
51    ///
52    /// When accessing from JS, the attribute will automatically be called `rawHandle`.
53    ///
54    /// Each canvas created by the windowing system should be assigned their own unique ID.
55    ///
56    /// [data attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*
57    pub id: u32,
58}
59
60impl WebWindowHandle {
61    /// Create a new handle to a canvas element.
62    ///
63    ///
64    /// # Example
65    ///
66    /// ```
67    /// # use raw_window_handle::WebWindowHandle;
68    /// #
69    /// let id: u32 = 0; // canvas.rawHandle;
70    /// let handle = WebWindowHandle::new(id);
71    /// ```
72    pub fn new(id: u32) -> Self {
73        Self { id }
74    }
75}
76
77/// Raw window handle for a Web canvas registered via [`wasm-bindgen`].
78///
79/// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
80#[non_exhaustive]
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
82pub struct WebCanvasWindowHandle {
83    /// A pointer to the [`JsValue`] of an [`HtmlCanvasElement`].
84    ///
85    /// Note: This uses [`c_void`] to avoid depending on `wasm-bindgen`
86    /// directly.
87    ///
88    /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html
89    /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html
90    //
91    // SAFETY: Not using `JsValue` is sound because `wasm-bindgen` guarantees
92    // that there's only one version of itself in any given binary, and hence
93    // we can't have a type-confusion where e.g. one library used `JsValue`
94    // from `v0.2` of `wasm-bindgen`, and another used `JsValue` from `v1.0`;
95    // the binary will simply fail to compile!
96    //
97    // Reference: TODO
98    pub obj: NonNull<c_void>,
99}
100
101impl WebCanvasWindowHandle {
102    /// Create a new handle from a pointer to [`HtmlCanvasElement`].
103    ///
104    /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html
105    ///
106    /// # Example
107    ///
108    /// ```
109    /// # use core::ffi::c_void;
110    /// # use core::ptr::NonNull;
111    /// # use raw_window_handle::WebCanvasWindowHandle;
112    /// # type HtmlCanvasElement = ();
113    /// # type JsValue = ();
114    /// let canvas: &HtmlCanvasElement;
115    /// # canvas = &();
116    /// let value: &JsValue = &canvas; // Deref to `JsValue`
117    /// let obj: NonNull<c_void> = NonNull::from(value).cast();
118    /// let mut handle = WebCanvasWindowHandle::new(obj);
119    /// ```
120    pub fn new(obj: NonNull<c_void>) -> Self {
121        Self { obj }
122    }
123}
124
125#[cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2"))]
126#[cfg_attr(
127    docsrs,
128    doc(cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2")))
129)]
130/// These implementations are only available when `wasm-bindgen-0-2` is enabled.
131impl WebCanvasWindowHandle {
132    /// Create a new `WebCanvasWindowHandle` from a [`wasm_bindgen::JsValue`].
133    ///
134    /// The `JsValue` should refer to a `HtmlCanvasElement`, and the lifetime
135    /// of the value should be at least as long as the lifetime of this.
136    pub fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self {
137        Self::new(NonNull::from(js_value).cast())
138    }
139
140    /// Convert to the underlying [`wasm_bindgen::JsValue`].
141    ///
142    /// # Safety
143    ///
144    /// The inner pointer must be valid. This is ensured if this handle was
145    /// borrowed from [`WindowHandle`][crate::WindowHandle].
146    pub unsafe fn as_wasm_bindgen_0_2(&self) -> &wasm_bindgen::JsValue {
147        unsafe { self.obj.cast().as_ref() }
148    }
149}
150
151/// Raw window handle for a Web offscreen canvas registered via
152/// [`wasm-bindgen`].
153///
154/// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
155#[non_exhaustive]
156#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
157pub struct WebOffscreenCanvasWindowHandle {
158    /// A pointer to the [`JsValue`] of an [`OffscreenCanvas`].
159    ///
160    /// Note: This uses [`c_void`] to avoid depending on `wasm-bindgen`
161    /// directly.
162    ///
163    /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html
164    /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html
165    //
166    // SAFETY: See WebCanvasWindowHandle.
167    pub obj: NonNull<c_void>,
168}
169
170impl WebOffscreenCanvasWindowHandle {
171    /// Create a new handle from a pointer to an [`OffscreenCanvas`].
172    ///
173    /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html
174    ///
175    /// # Example
176    ///
177    /// ```
178    /// # use core::ffi::c_void;
179    /// # use core::ptr::NonNull;
180    /// # use raw_window_handle::WebOffscreenCanvasWindowHandle;
181    /// # type OffscreenCanvas = ();
182    /// # type JsValue = ();
183    /// let canvas: &OffscreenCanvas;
184    /// # canvas = &();
185    /// let value: &JsValue = &canvas; // Deref to `JsValue`
186    /// let obj: NonNull<c_void> = NonNull::from(value).cast();
187    /// let mut handle = WebOffscreenCanvasWindowHandle::new(obj);
188    /// ```
189    pub fn new(obj: NonNull<c_void>) -> Self {
190        Self { obj }
191    }
192}
193
194#[cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2"))]
195#[cfg_attr(
196    docsrs,
197    doc(cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2")))
198)]
199/// These implementations are only available when `wasm-bindgen-0-2` is enabled.
200impl WebOffscreenCanvasWindowHandle {
201    /// Create a new `WebOffscreenCanvasWindowHandle` from a
202    /// [`wasm_bindgen::JsValue`].
203    ///
204    /// The `JsValue` should refer to a `HtmlCanvasElement`, and the lifetime
205    /// of the value should be at least as long as the lifetime of this.
206    pub fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self {
207        Self::new(NonNull::from(js_value).cast())
208    }
209
210    /// Convert to the underlying [`wasm_bindgen::JsValue`].
211    ///
212    /// # Safety
213    ///
214    /// The inner pointer must be valid. This is ensured if this handle was
215    /// borrowed from [`WindowHandle`][crate::WindowHandle].
216    pub unsafe fn as_wasm_bindgen_0_2(&self) -> &wasm_bindgen::JsValue {
217        unsafe { self.obj.cast().as_ref() }
218    }
219}