fission-shell-winit
Shared winit + Vello runtime for Fission applications.
This crate holds the common event loop, rendering pipeline, input routing, and test-control
transport used by both fission-shell-desktop and fission-shell-mobile.
Architecture
WinitApp<S, W>
|
+-- Runtime (fission-core: state management, action dispatch, animation ticking)
+-- LayoutEngine (fission-layout: flexbox layout computation)
+-- Pipeline (IR diffing, layout, paint, display list generation)
+-- VelloRenderer (fission-render-vello: GPU rasterization via Vello + wgpu)
+-- VelloTextMeasurer (font context, text shaping via Parley + Fontique)
+-- DesktopClipboard (or in-memory clipboard fallback on mobile)
+-- DesktopImeHandler (IME composition via winit)
+-- VideoBackend (macOS AVFoundation video, or mock on other platforms)
+-- TestControl (optional HTTP server for automated UI testing)
The main entry point is WinitApp::new(root_widget), which creates a winit event loop and runs
the full build-layout-paint-present cycle on every frame.
WinitApp
The generic WinitApp<S, W> owns the shared application lifecycle.
Construction
use WinitApp;
new
.with_title
.with_state_init
.with_startup_action
.with_async
.with_key_handler
.with_sync_env
.with_frame_hook
.with_async
.run
.unwrap;
Builder methods
| Method | Purpose |
|---|---|
with_title(title) |
Set the window title. |
with_state_init(f) |
Mutate the initial S state before the first frame. Keep this synchronous and cheap. |
with_startup_action(action) |
Dispatch one action after the runtime is ready. Use this to kick off startup jobs or services without blocking first paint. |
with_async(f) |
Register typed async jobs, services, and capability handlers on the shell-owned async host. |
with_key_handler(f) |
Register an app-level key handler that intercepts before the framework. The handler receives (&mut S, &KeyCode, modifiers) and returns true if consumed. |
with_sync_env(f) |
Synchronize Env from app state each frame (e.g., theme switching). |
with_frame_hook(f) |
Register a callback that runs on every AboutToWait event. Return true to request a redraw. Prefer startup actions, async jobs, services, or timer resources for app lifecycle work. |
with_env(env) |
Replace the default Env. |
register_reducer(id, f) |
Register a single action reducer. |
absorb_registry(registry) |
Absorb an entire ActionRegistry<S> for bulk reducer registration. |
Frame cycle
Each RedrawRequested event triggers:
- Effect drain -- pending effects from the previous frame are dispatched.
- Build -- the root component converts into a
Widgettree; portals are collected. - InternalLower -- the
Widgettree is lowered toCoreIR(intermediate representation). - Pipeline update -- IR diff, layout computation, display list generation.
- Render -- Vello rasterizes the display list to a GPU texture.
- Present -- the texture is blitted to the window surface.
Pipeline
The render pipeline (Pipeline) manages incremental updates:
- IR diffing via
fission-core::diff::diff_iridentifies structurally changed nodes. - Incremental layout only recomputes dirty subtrees (unless the viewport resized).
- Paint caching stores display list segments per node, keyed by content hash.
- Video surface collection extracts video embed rects for platform compositing.
Key fields
| Field | Purpose |
|---|---|
prev_ir |
The CoreIR from the previous frame (used for diffing). |
last_snapshot |
The most recent LayoutSnapshot with computed rects for every node. |
paint_cache |
Per-node display list cache: HashMap<WidgetId, (hash, Vec<DisplayOp>)>. |
video_surfaces |
Video rects to hand off to the platform video backend. |
Environment variables
| Variable | Default | Purpose |
|---|---|---|
FISSION_MAX_FPS |
60 |
Maximum frame rate (throttled via WaitUntil). |
FISSION_RENDERER |
auto |
Select the renderer. Native targets accept auto, native-vello-gpu, native-vello-cpu, or native-software. Web accepts auto, webgpu-vello, or canvas2d-software via globalThis.FISSION_RENDERER or the ?fission_renderer= query parameter. |
FISSION_VELLO_USE_CPU |
false |
Native compatibility escape hatch that asks Vello to use its CPU mode while still presenting through the GPU surface. |
FISSION_TEXTINPUT_BLINK |
true |
Enable/disable cursor blinking in text inputs. |
FISSION_TEXTINPUT_BLINK_MS |
530 |
Cursor blink period in milliseconds. |
FISSION_USE_SYSTEM_FONTS |
false |
Include system fonts in the font collection. |
FISSION_TEXT_TRACE |
false |
Enable text input latency tracing to stderr. |
FISSION_SCROLL_TRACE |
false |
Enable scroll event tracing to stderr. |
FISSION_TEST_CONTROL_PORT |
(none) | Start an HTTP test control server on this port. |
Test control
When FISSION_TEST_CONTROL_PORT is set, the shell spawns a TCP server that accepts JSON commands from fission-test-driver::LiveTestClient. This enables automated UI testing by sending tap, scroll, type, screenshot, and semantic tree queries over HTTP. See the fission-test-driver crate for the client API.
Platform support
- Desktop: used by
fission-shell-desktop - iOS / Android: used by
fission-shell-mobile - Web: used by
fission-shell-web; WebGPU/Vello is the default renderer when the browser exposes a usable WebGPU adapter, and Canvas2D/software remains the compatibility fallback.