frankenapps
frankenapps

Reputation: 8261

How to implement HasDisplayHandle and HasWindowHandle for a HtmlCanvasElement in raw_window_handle 0.6?

How can I implement HasWindowHandle and HasDisplayHandle for a web_sys::HtmlCanvasElement?

This is what I tried, but it does not compile due to display_handle and window_handle being of wrong types, not matching the function signature. I guess I would somehow need to cast, but I am unable to figure out how.

struct WindowCanvas {
    display_handle: raw_window_handle::WebDisplayHandle,
    window_handle: raw_window_handle::WebWindowHandle,
}

impl raw_window_handle::HasWindowHandle for WgpuCanvas {
    fn window_handle(&self) -> Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError> {
        Ok(self.window_handle)
    }
}

impl raw_window_handle::HasDisplayHandle for WgpuCanvas {
    fn display_handle(&self) -> Result<raw_window_handle::DisplayHandle<'_>, raw_window_handle::HandleError> {
        Ok(self.display_handle)
    }
}

My previous implementation using raw_window_handle 0.5 in conjunction with the now deprecated HasRawWindowHandle and HasRawDisplayHandletraits:

struct WindowCanvas {
    display_handle: raw_window_handle::WebDisplayHandle,
    window_handle: raw_window_handle::WebWindowHandle,
}

unsafe impl raw_window_handle::HasRawWindowHandle for WgpuCanvas {
    fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
        raw_window_handle::RawWindowHandle::Web(self.window_handle)
    }
}

unsafe impl raw_window_handle::HasRawDisplayHandle for WindowCanvas {
    fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle {
        raw_window_handle::RawDisplayHandle::Web(self.display_handle)
    }
}

And this is how I would use it:

let window = web_sys::window().expect("Can not get browser window.");
let document = window.document().expect("Can not get html document.");
let canvas = document
    .get_element_by_id("i1")
    .expect("The given canvas id was not found in the document.");

let canvas: web_sys::HtmlCanvasElement = canvas
    .dyn_into::<web_sys::HtmlCanvasElement>()
    .expect("Failed to convert element to canvas.");

// The numeric id for the `raw-window_handle` is retrieved from the id of
// the canvas minus the first char.
let mut id = canvas.id();
id.replace_range(0..1, "");

// The numeric id in the `raw_window_handle::web::WebHandle` has to be set
// inside the `data-raw-handle` attribute of the canvas.
canvas
    .set_attribute("data-raw-handle", id.as_str())
    .expect("Failed to assign numeric raw-window-handle id to canvas.");

// Raw-window-handle expects a numeric identifier.
let id: u32 = id
    .parse()
    .expect("Failed to get numeric sequence from canvas id.");

// Now to link the canvas with the window handle, create a handle
// with the data-raw-handle value of the canvas as the id of the window handle.
let window_handle = raw_window_handle::WebWindowHandle::new(id);

// Construct an empty display handle for the web.
let display_handle = raw_window_handle::WebDisplayHandle::new();

let window_canvas = WindowCanvas {
    display_handle,
    window_handle,
};

P.S.: I know WebCanvasWindowHandle is better suited for my usecase, but the general question remains the same.

Upvotes: 0

Views: 45

Answers (0)

Related Questions