Skip to main content

Winit Harness (WgpuHtmlWindow)

The wgpu-html-winit crate provides a batteries-included window harness. It handles window setup, input forwarding, focus management, scrolling, clipboard, and screenshots.

One-Call Setup

use wgpu_html_winit::create_window;

let mut tree = Tree::new(root_node);

create_window(&mut tree)
.with_title("My wgpu-html App")
.with_size(1280, 720)
.with_exit_on_escape(true)
.with_clipboard_enabled(true)
.with_screenshot_key(winit::keyboard::KeyCode::F12)
.with_hook(MyHook)
.run()
.unwrap();

WgpuHtmlWindow

Wraps &mut Tree and provides chainable configuration:

MethodDefaultDescription
with_title(s)"wgpu-html"Window title
with_size(w, h)(1280, 720)Logical size
with_exit_on_escape(b)trueEsc closes the window
with_clipboard_enabled(b)trueCtrl+A/Ctrl+C support
with_screenshot_key(k)F12Screenshot key
with_hook(h)NoneAppHook callbacks
run()Starts the event loop (blocking)

AppHook Trait

pub trait AppHook {
fn on_key(&mut self, ctx: HookContext<'_>, event: &KeyEvent) -> EventResponse { ... }
fn on_frame(&mut self, ctx: HookContext<'_>, timings: &FrameTimings) { ... }
fn on_pointer_move(&mut self, ctx: HookContext<'_>, pointer_move_ms: f64, changed: bool) { ... }
fn on_idle(&mut self) { ... }
fn on_window_event(&mut self, ctx: HookContext<'_>, window_id: WindowId, event: &WindowEvent) -> bool { ... }
}
  • on_key: Called before built-in keyboard handling. Return EventResponse::Stop to skip defaults.
  • on_frame: Called after each GPU frame submission. Receives timing breakdown.
  • on_pointer_move: Called after pointer dispatch.
  • on_idle: Called once per event-loop iteration after all events are dispatched.

HookContext

pub struct HookContext<'a> {
pub tree: &'a mut Tree,
pub renderer: &'a mut Renderer,
pub text_ctx: &'a mut TextContext,
pub image_cache: &'a mut ImageCache,
pub last_layout: Option<&'a LayoutBox>,
pub window: &'a Arc<Window>,
pub event_loop: &'a ActiveEventLoop,
}

FrameTimings

pub struct FrameTimings {
pub frame_index: u64,
pub cascade_ms: f64,
pub layout_ms: f64,
pub paint_ms: f64,
pub render_ms: f64,
pub total_ms: f64,
}

Built-In Features

FeatureKey/Behavior
Viewport scrollMouse wheel
Scrollbar dragClick-drag on the scrollbar thumb
ClipboardCtrl+A select all, Ctrl+C copy
ScreenshotF12 → screenshot_*.png
Tab navigationTab / Shift+Tab focus cycling
Escape exitEsc closes the window

Type Translators

pub fn mouse_button(button: WinitMouseButton) -> wgpu_html_tree::MouseButton;
pub fn key_to_dom_key(key: &str) -> String;
pub fn keycode_to_dom_code(code: KeyCode) -> String;
pub fn keycode_to_modifier(code: KeyCode) -> Option<Modifier>;

These map winit's key/mouse types to wgpu-html's internal types.

System Font Discovery

use wgpu_html_winit::discover_system_fonts;

let variants = discover_system_fonts(); // Vec<SystemFontVariant>

Convenience wrappers around system_font_variants() and register_system_fonts().

Complete Example

use wgpu_html::{parser, tree::{Tree, Node, Element}};
use wgpu_html_winit::create_window;

let html = r#"<html><body>
<h1>Hello from wgpu-html!</h1>
<button id="btn">Click me</button>
</body></html>"#;

let document = parser::parse(html);
let mut tree = Tree::new(Node::root(document));

// Register fonts
wgpu_html::tree::register_system_fonts(&mut tree, "sans-serif");

// Hook to handle custom logic
struct MyApp;
impl wgpu_html_winit::AppHook for MyApp {
fn on_frame(&mut self, ctx: wgpu_html_winit::HookContext<'_>, t: &wgpu_html_winit::FrameTimings) {
// Called every frame — access tree, renderer, layout
}
}

create_window(&mut tree)
.with_title("My App")
.with_size(1024, 768)
.with_hook(MyApp)
.run()
.unwrap();