Skip to content

sparkles:wsi — Feature requirements

Normative requirement ledger for SPEC.md. planned means the contract is accepted but has no implementation evidence; partial names the missing platform or semantic edge; verified requires the evidence described in SPEC §11.

Last reviewed: August 21, 2026

Architecture (WSI)

IDRequirementStatusTraces to
WSI1The native desktop package is named sparkles:wsi and has no third-party cross-platform windowing, widget, or renderer dependency. Native platform client libraries are permitted.partial — package/core and all four native lifecycle modules delivered; the full desktop baseline remainslibs/wsi; SPEC §1
WSI2Wayland, X11, Win32, and AppKit are peer native backends behind one value-level contract. No supported desktop silently falls through to SDL.partial — all four native lifecycle adapters are peers; the common facade and full feature parity remainplatform.*; SPEC §9
WSI3Event Horizon is the only application event loop, scheduler, timer source, blocking wait, and cross-thread wake path.partial — Wayland/XCB over uring plus User32/IOCP and CFRunLoop/kqueue combined waits delivered; HITL and race coverage remainloop; SPEC §4
WSI4The UI/main thread owns all windows and native callbacks; cross-thread work is value commands plus a coalescing waker.partial — all four backends enforce their owner/main thread and non-reentrant drains; the portable command surface remainsloop; SPEC §3
WSI5WSI events, ids, configurations, and commands are Regular values with explicit lifetime and generation rules.partial — owned event algebra and generation-safe lifecycles delivered on all four backends, including keyboard, pointer button/motion/enter/leave, and scroll values; native command algebra remainstypes, events, loop, platform.*
WSI6Platform and renderer failures use typed WsiError/Expected, not assertions, sentinel handles, or IoError.partial — allocation-free error/result path and all four native lifecycle mappings delivered; renderer mappings remaintypes, loop, platform.*
WSI7SDL 3 compatibility, Vulkan surface/swapchain integration, and Skia Graphite live in separate packages above native WSI.partial — native surface/context and shared presentation resources live in sparkles:vulkan-wsi; the SDL host package and Graphite remainSPEC §10
WSI8Shared Sparkles primitives are reused or moved to the lowest owning package; WSI does not introduce parallel geometry, pointer-shape, cell-metric, UTF conversion, or event-loop implementations.partial — shared foundations and all four native Event Horizon consumers are delivered; future integration must preserve that reusePLAN M1

Desktop feature baseline (F01F17)

Every row applies independently to Wayland, X11, Win32, and AppKit unless the row says otherwise. The first implementation may stage platforms, but the native baseline does not complete until all four columns are verified.

IDRequirementStatusPrincipal evidence
F01First pixel and initialization: create one window, deliver authoritative logical/physical metrics and stable renderer handles, and reach a presentable first frame without an avoidable round trip or created-at-wrong-scale frame.partial — all four native backends deliver metrics, typed handles and expose/frame-ready opportunities; Wayland bootstraps asynchronously; renderer present and HITL remainnative lifecycle smokes; first-frame traces per platform
F02Resize: preserve continuous live resize, report every authoritative surface-size transition in order, acknowledge protocol requests promptly, and never resize a swapchain from logical size.partial — programmatic transitions pass on all four backends and Wayland configure is acked in the listener; interactive/modal and renderer paths remainnative lifecycle smokes; latency/HITL traces
F03Modal-loop survival: continue native replies, input queuing, repaint opportunities, and Event Horizon wake progress during move/size/menu/modal tracking loops.plannedmodal-loop scenarios per platform
F04Frame pacing: expose native frame opportunities/presentation timing where available and an Event Horizon deadline fallback without sleeping inside WSI.plannedcadence/jitter trace
F05Loop wakeup and external sources: integrate native readiness with Event Horizon, provide a contention-safe coalesced cross-thread wake, and never run a second blocking application loop.partial — all four native waits share Event Horizon with a timer and foreign-thread waker; HITL, wake-race and zero-idle coverage remainnative loop smokes; wake-race and zero-idle tests
F06Keyboard and keymap: report physical and logical key identity, location, modifiers, press/repeat/release, keymap/layout changes, and unknown native codes without inventing text.partial — physical identity, location, modifiers, press/repeat/release and layout-derived unshifted logical keys are queued on all four backends (xkbcommon compiles the Wayland keymap fd and the X11 core device's map; Win32 maps MAPVK_VK_TO_CHAR; AppKit reads charactersIgnoringModifiers, with function keys as named private-range scalars); Wayland synthesizes client-side repeat from repeat_info on an Event Horizon timer; keymap-change events and native-Windows evidence remainWin32 Wine smoke; layout/repeat/keymap matrix
F07IME and text input: separate UTF-8 commit from keys; report pre-edit, selection and cursor/segments; position candidate UI; use text-input-v3, XIM, IMM32 first, and NSTextInputClient.partial — Win32 UTF-16 commits and IMM32 pre-edit/attributes/cursor/result are queued as owned UTF-8, and Wayland binds per-seat text-input-v3 (auto-enabled on the compositor's enter, double-buffered batches applied on done: commit before pre-edit, byte-offset cursor/selection, one composition-end event); X11 speaks XIM through xcb-imdkit's client on the backend's single XCB connection (keys forward through a live input context and bounce back unconsumed; commits arrive as owned UTF-8), verified end-to-end against an in-tree test XIM server; AppKit adopts NSTextInputClient (runtime protocol registration; keyDown routes through the view's input context, insertText commits, setMarkedText maps UTF-16-unit selection to byte offsets); candidate placement, callback-style XIM pre-edit, and Wayland live-IME evidence remain (Weston implements only text-input-v1, so that column's runtime proof is owed to a v3 compositor)Wine IMM32 self-injection; native IME scenarios
F08DPI and runtime rescale: use logical public geometry plus authoritative physical surface size and scale; handle mixed-DPI movement atomically where the platform permits.partial — Wayland derives the window scale from its entered outputs (maximum policy), requests the matching buffer scale, and reports one atomic logical/physical/scale transition, verified at scale 2 under Weston; Win32 reports GetDpiForWindow with WM_DPICHANGED transitions (per-monitor evidence owed to native Windows — Wine monitors are fixed at 96 DPI); AppKit reports the backing scale; X11 scale detection and mixed-DPI movement remainmixed-output scale test
F09Outputs: enumerate, add/change/remove displays with identity, geometry/work area, scale, modes and refresh; report the active output set of each window.partial — Wayland binds outputs, tracks each window's entered-output set (OutputEnteredEvent) and per-output scale; output identity/geometry/modes, hotplug reporting and the other platforms remainhotplug/topology test
F10Pointer capture: support capture/confinement and raw relative motion as distinct capabilities; preserve releases outside content and unwind capture on focus loss/destruction.partial — drag release-outside-content is preserved and verified on X11 (automatic core grab, outside coordinates asserted under Xvfb), Win32 (implicit SetCapture spanning first press to last release, engagement proven via GetCapture under Wine, unwound on WM_CAPTURECHANGED), and AppKit (window-tracked drag routing); explicit capture/confinement, raw relative motion, and focus-loss unwind coverage remaindrag-outside/raw-motion test
F11Scroll fidelity: preserve pixel/logical delta, discrete steps, source, phase/momentum and natural-direction metadata where supplied; normalization happens above WSI.partial — delta, discrete steps, source, unit and the natural-direction flag are queued on all four backends (Wayland axis frames with axis_source/axis_discrete, X11 legacy wheel buttons, Win32 wheel deltas, AppKit precise pixel deltas); phase/momentum and trackpad fidelity evidence remainmouse/trackpad trace fixtures
F12Cursors: support standard shapes through the shared PointerShape, custom images/hotspots, visibility and scale changes; report unsupported shapes.partial — the seven shared PointerShape shapes and per-window visibility on all four backends: server-side cursor-shape-v1 on Wayland (typed unsupported without the global), core cursor-font glyphs on X11 (grab/grabbing approximate as fleur), stock IDC_* applied on WM_SETCURSOR for Win32 (grab/grabbing approximate as IDC_SIZEALL), stock NSCursor on AppKit (all seven exact); custom images/hotspots, cursor scale and the manual catalog pass remaincursor catalog/manual pass
F13Decorations: on Wayland request xdg-decoration SSD and provide renderer-drawn CSD fallback without libdecor; report frame actions and correct input regions. Other platforms use their native equivalent.plannedGNOME and SSD compositor passes
F14Window state and vetoable close: report minimize/maximize/fullscreen/focus/occlusion and allow close requests to be accepted or vetoed without duplicate destruction.plannedstate-transition model tests
F15Grabbed popup: create anchored/gravity-constrained native popups with a compositor/server grab, reposition feedback and outside-dismiss semantics.plannednested/reposition/dismiss scenarios
F16Clipboard and drag-and-drop: offer and receive typed data incrementally, negotiate MIME/format choices, handle large transfers without blocking, and implement both drag source and target.plannedround-trip/large-transfer matrix
F17Threading and reentrancy: enforce the UI/main-thread rule, never call application code re-entrantly from native callbacks, and make shutdown/cancellation race-safe.partial — all four backends queue callbacks and reject wrong-thread calls; both Linux poll paths have cancellation-safe teardown; modal/native races remainrecording lifecycle plus native loop smokes

Handoff and integration (INT)

IDRequirementStatusTraces to
INT1NativeHandles is a closed typed sum with only backend-valid fields and a documented ready-to-destroy lifetime.partial — live Wayland display/surface, XCB connection/window/visual, HWND/HINSTANCE and NSApplication/NSWindow/NSView queries plus recording unsupported are exercisedhandles; native loop smokes; SPEC §8
INT2sparkles:vulkan-wsi creates native Vulkan surfaces and reuses the loader, command tables, error vocabulary, and proven frame/swapchain retirement policy.partial — typed Wayland/XCB/Win32 surfaces, present-device selection, command pools, frame sync, swapchain decisions and deferred retirement are shared; the native Wayland frame loop presents under sync validation with compositor resize, and the X11/Win32 runtime probes reach a present-capable device on the live ICD; X11/Win32/macOS native presents remainlibs/vulkan-wsi; examples/native-wayland-triangle.d; unchanged SDL triangle build
INT3Skia Graphite uses Vulkan on Linux/Windows and Metal on macOS without WSI importing Skia or either graphics API.plannedlibs/ui-skia
INT4sparkles:ui-app exposes tui, gui-skia (default GUI), gui-skia-sdl, gui-raylib, and full configurations while application source remains backend-neutral.plannedlibs/ui-app/dub.sdl
INT5The UI adapter converts the lossless WSI vocabulary into sparkles:input once, using shared cell-metric and capability policies.plannedui-app/input adapter
INT6Every capability-bearing commit updates the supported-feature matrix and points at its automated and HITL evidence.partial — every native slice so far has updated the ledger with automated evidence; the named HITL lanes remain incompletecomparison.md

Deferred (POST)

IDRequirementStatusEntry condition
POST1Replace or augment Win32 IMM32 with TSF without changing the public composition/commit contract.deferrednative F01F17, Graphite, and ui-app integration verified
POST2Add Android/iOS backends without weakening the callback/lifecycle and typed-handle contracts.deferreddesktop baseline verified