Build a real Wayland client as wasm32-wasip1 and run it inside Wawona via Relay’s Runtime (wasm / wpm). Full import table: Wasm host ABI. User install path: WASM / WASI.
What you are building
A guest that speaks the same protocols as a Linux weston-simple-shm:
wl_compositor+wl_surfacewl_shm+ pool/buffer (XRGB8888 or ARGB8888)xdg_wm_base/xdg_surface/xdg_toplevel
Pixels go into Wawona’s compositor (iland present on Apple/Android). There is no Wawona-specific draw API. Host imports only fix WASI gaps: unix connect to WAYLAND_DISPLAY, anonymous SHM, and SCM_RIGHTS on sendmsg.
Port fidelity: if the same client built on Linux and streamed over waypipe looks different, the wasm port is wrong, not the compositor. See Porting.
Prerequisites
- A live Wayland display from Wawona (start a Machines session / nested weston/niri, or run under the host compositor).
WAYLAND_DISPLAYand usuallyXDG_RUNTIME_DIRmust be set (Runtime defaultsXDG_RUNTIME_DIR=/tmp/wawona-$UID,WAYLAND_DISPLAY=wayland-0). - Toolchain for
wasm32-wasip1(Rust, Go, Swift, wasi-sdk, Zig, …). - Relay Runtime on PATH inside the shell (
wasm), orwpm installthenwasm <name>.
Minimal sequence
1. wawona_wayland_connect(&wl_fd)
2. wl_display.get_registry + sync; bind compositor, shm, xdg_wm_base
3. create_surface → get_xdg_surface → get_toplevel → set_title → commit
4. wawona_wayland_shm_create(size, &shm_fd)
5. Paint pixels in guest memory → wawona_wayland_shm_write(shm_fd, …)
6. wl_shm.create_pool via wawona_wayland_sendmsg(wl, req, len, shm_fd)
7. create_buffer, wait xdg_surface.configure, ack_configure
8. attach + damage + commit
9. Event loop: wawona_socket_recv on wl_fd; handle ping, configure, closeUse wawona_wayland_sendmsg for every request that needs an fd, and for ordinary requests with scm_fd = -1 if you route all traffic through the host helper. Protocol detail: PROTOCOL.md.
Starter templates
| Goal | Example | Notes |
|---|---|---|
| Smallest GUI smoke | hello-wasi-gui | One buffer. Bundled on every product target |
| Interactive SHM | wayland-shm | Seat, resize, checkbox, typing. Rust / Go / Swift |
| Full Wayland app (catalog) | chess-wawona | Chess + variants; see showcase below |
| CLI + TCP | examples/rust | Sockets only |
cd Relay/import/wasm/examples/hello-wasi-gui/rust && ./build.sh
# artifact: dist/hello-wasi-gui.wasm
# In Wawona shell:
wasm ./hello-wasi-gui.wasm
# or:
wpm install ./hello-wasi-gui.wasm
wasm hello-wasi-guirustup target add wasm32-wasip1
cargo build --target wasm32-wasip1 --releaseShowcase: chess-wawona
Published Mode A package on repo.wawona.io/wasm/v1. Source: chess-for-linux/wasm (GPL-3.0-or-later). Same rules/engine Rust as the native Linux app; the wasm frontend is a real Wayland client (wl_compositor, wl_shm, xdg_wm_base, wl_seat). No Qt, no browser. Optional wawona_vk_* host imports can paint the Wood 3D scene when present; pixels still leave through wl_shm. Without those imports, the software 2D board runs.
In a Wawona shell with a live compositor:
wpm install chess-wawona
wasm chess-wawonaControls (2D path): click/tap piece then destination; type UCI/SAN and Enter; Crazyhouse drops like N@e4; on-screen New / Undo / Redo / AI / Variant (Standard, Crazyhouse, Suicide, Losers). No file save or network in this build.
Build from source (developers):
git clone https://github.com/cube-one-ber/chess-for-linux
cd chess-for-linux
rustup target add wasm32-wasip1
./scripts/build-wasm.sh
# → artifacts/wasm/packages/chess-wawona/<version>/component.wasm
wasm ./artifacts/wasm/packages/chess-wawona/*/component.wasmUse this as the reference for a non-trivial Wayland wasm app: host ABI for connect + SHM + seat traffic, catalog kind: wayland, honest package version, and port fidelity against the Linux client.
Publishing to the catalog
- Package is bytecode under
/wasm/v1(Mode A). See repo.wawona.io wasm-abi andWawona/wasm-packages. - Catalog
versionis the software version, not the ABI label. - Prefer a real upstream port with the upstream release version. Scratch demos use honest
wawona-*names. - GUI packages still speak protocol bytes, not a private host draw ABI.
Browse: repo.wawona.io/search/?channel=wasm.
GPU / EGL / Vulkan
| Path | Status |
|---|---|
wl_shm + xdg | Supported portable GUI (required smoke: hello-wasi-gui) |
| Wayland-EGL / GLES via ANGLE | Native clients first; wasm GPU is not the store baseline |
wawona_vk_* board imports | Experimental; not the Wayland contract |
| watchOS | SHM + SpriteKit present only. No Metal/GLES wasm |
Do not re-host a Wayland client onto a fake KMS path because EGL is unfinished.
Hard rejects
- Custom
wawona_draw_*instead of Wayland - Assuming host TLS (
wawona_socket_tls_connect_hostisENOSYS) - Mixing WASI fds with host Wayland/SHM fds
- Shipping Cranelift /
MAP_JITfor store Apple mobile - Claiming the guest is a VM or container
Related
- Wasm host ABI
- Porting
- WASM / WASI (users)
- Gate: Wawona workflow
wasm-wayland.yml