Documentation
¶
Overview ¶
Package wasmbox implements the client half of the wasmdesk/wasmbox external-client wire protocol, so a go-widgets application can run as a client of the browser compositor exactly as it runs on X11 or Wayland.
This file is the SOVEREIGN, transport-agnostic codec: the wire messages (hello/welcome/commit/input/set_title/request_close/closed), the SAB damage-rectangle maths and the input→toolkit.Event mapping, all expressed over plain Go values (JSON-cloneable map[string]any and structs). It carries NO syscall/js dependency, so it builds — and is unit-tested to 100% — on every GOOS. The thin syscall/js glue that actually allocates the SharedArrayBuffer and posts/receives messages over the compositor MessagePort lives in client_js.go (//go:build js && wasm) and drives everything here.
The wire contract mirrored here is wasmdesk/wasmbox's docs/protocol.md; the wasmbox repository itself is unmodified — this is a pure client-side backend.
Index ¶
- Constants
- func DecodeClosed(m map[string]any) (windowID int, reason string, err error)
- func EncodeCommit(windowID int, damage Rect) map[string]any
- func EncodeHello(h Hello) map[string]any
- func EncodeRequestClose(windowID int) map[string]any
- func EncodeSetTitle(windowID int, title string) map[string]any
- func MapInput(ev InputEvent, buttonHeld bool) []toolkit.Event
- func MessageKind(m map[string]any) string
- func RowSpan(r Rect, stride int) (startByte, rowBytes int)
- type Hello
- type InputEvent
- type Rect
- type Welcome
Constants ¶
const ( KindHello = "hello" KindWelcome = "welcome" KindCommit = "commit" KindInput = "input" KindSetTitle = "set_title" KindRequestClose = "request_close" KindClosed = "closed" )
Message type discriminants (the JSON `type` field), matching docs/protocol.md.
const ( InMouseDown = "mousedown" InMouseUp = "mouseup" InMouseMove = "mousemove" InWheel = "wheel" InKeyDown = "keydown" InKeyUp = "keyup" )
Mouse/keyboard input kinds carried by input.event.kind.
const RoleWindow = "window"
RoleWindow is the default surface role (a normal, decorated, focusable window). The backend only ever opens window-role surfaces.
Variables ¶
This section is empty.
Functions ¶
func DecodeClosed ¶
DecodeClosed parses a `closed` message.
func EncodeCommit ¶
EncodeCommit builds a `commit` message naming the damaged sub-rectangle.
func EncodeHello ¶
EncodeHello builds the JSON-cloneable `hello` message body (minus the live SAB/ctl JS handles, which the transport attaches). role is always "window".
func EncodeRequestClose ¶
EncodeRequestClose builds a `request_close` message.
func EncodeSetTitle ¶
EncodeSetTitle builds a `set_title` message.
func MapInput ¶
func MapInput(ev InputEvent, buttonHeld bool) []toolkit.Event
MapInput translates one decoded wasmbox input event into the toolkit event(s) it produces, mapping kind/x/y/button/key/code/dx/dy to the toolkit event model exactly as the X11 and Wayland backends do:
- mousedown → EventClick (all buttons, mirroring X11 ButtonPress 1–3)
- mouseup → EventMouseUp
- mousemove → EventMouseDrag when a button is held, else EventMouseMove
- wheel → EventScroll with Delta normalised to −1 (up/back) / +1 (down/forward), matching the X11 wheel-button mapping; the vertical delta wins, falling back to the horizontal delta when dy is zero
- keydown → a named key (len>1, e.g. "Enter"/"ArrowLeft") yields one EventKeyDown carrying that name in Code; a printable key (a single rune) yields EventKeyDown+EventChar, Char being the committed rune — the same press/char split the X11 backend performs
- keyup → the symmetric single EventKeyUp
- modifier keys (Shift/Control/Alt/Meta/…) deliver nothing, mirroring X11's IsModifier suppression
buttonHeld carries the transport's pointer-button state so mousemove can pick drag vs move statelessly (the X11/Wayland backends read it from the event's own state mask; wasmbox input carries none, so the transport tracks it). The result is nil when the event maps to no toolkit event.
func MessageKind ¶
MessageKind returns the message's `type` discriminant, or "" when absent.
func RowSpan ¶
RowSpan returns, for a clamped rectangle over a surface of the given bytes-per-row stride, the byte offset of its first pixel and the number of bytes in one of its rows — the coordinates a transport uses to copy just the damaged rows into the SAB (4 bytes/pixel, row-major, top-left origin).
Types ¶
type Hello ¶
Hello is the client's opening handshake message. The SharedArrayBuffer and the (optional) seqlock control word are attached by the syscall/js layer as live JS handles; every scalar field of the wire message is produced here.
type InputEvent ¶
type InputEvent struct {
Kind string // mousedown | mouseup | mousemove | wheel | keydown | keyup
X, Y int
Button int
Key string
Code string
DX, DY int
}
InputEvent is one decoded `input.event` payload. Fields not carried by a given kind are zero (e.g. Key/Code are empty for mouse events; X/Y are zero for keyboard events).
func DecodeInput ¶
func DecodeInput(m map[string]any) (windowID int, ev InputEvent, err error)
DecodeInput parses an `input` message into the target window id and the event payload.
type Rect ¶
type Rect struct{ X, Y, W, H int }
Rect is a surface-local rectangle in pixels, matching toolkit.Rect's shape but kept local so the codec stays a leaf with a single toolkit dependency (the event model). Conversions are trivial.