Skip to content

EFX/IMG acceptance demos ​

Every feature in effects.md that a person can look at, and the command that shows it. Each one is runnable from a clean checkout inside nix develop, and each says what you should see — so a reviewer can accept or reject it without reading the diff.

Two conventions:

  • A GUI demo runs under xvfb-run so it needs no display, and writes a PNG. Drop the xvfb-run and the capture variable to watch it live instead. The env -u WAYLAND_DISPLAY -u XDG_RUNTIME_DIR is not decoration: with a Wayland session in the environment, GLFW prefers it over the Xvfb display xvfb-run just started, and the window opens on the real desktop.
  • A terminal demo writes ANSI to stdout. Pipe it to less -R, or run the binary without --render for the interactive version.

Build once: dub build :ui-gallery && dub build :hue.

Images (IMG1–IMG5) ​

#What it showsCommandExpected
D1An image lays out as an ordinary box, and a cell grid degrades it visiblydub run :ui-gallery -q -- --render-plain --page primitivesAn image row whose specimen is the swatch rastered in sextants (🬭🬂🬭🬂…, GLY9) in the 8×2 cells the image's pixel size resolved to; with --profile baseline it reads [a colo] — the alt text, bracketed and truncated to the same cells
D2The same handle drawn as real pixels on the GPUxvfb-run -a env -u WAYLAND_DISPLAY -u XDG_RUNTIME_DIR UIG_SHOT=/tmp/img.png ./apps/ui-gallery/build/ui-gallery --gui --page primitives/tmp/img.png shows a colour-swatch image where the terminal showed [a colo]
D3contain preserves aspect; an unregistered handle falls backxvfb-run -a env -u WAYLAND_DISPLAY -u XDG_RUNTIME_DIR IMGSHOT=/tmp/fit.png dub run --single docs/specs/ui/demos/imgshot.dThree panels: intrinsic size, a 40×12 box letterboxed, and [not re] for a handle nothing registered

The bracket and tier 0 (EFX1–EFX10, EFX24) ​

#What it showsCommandExpected
D4Tier-0 effects running in a terminal — the claim EFX24 exists to make falsifiabledub run :ui-gallery -q -- --render --page effectsFive panels of identical widgets: none plain, scanlines with alternating darkened rows, phosphor green, dim uniformly darker, spectrum a 24-bit hue sweep across the columns
D5Nesting composes with ancestors rather than replacing them (EFX2)same as D4, scroll to "nesting · dim inside dim"The inner panel is visibly darker than the outer one — it took both
D6A bracket never moves anything (EFX6)dub test :ui -- -i "ui.displayList.effect"Frames identical with and without the effect; the op stream is the plain one plus exactly two ops

Tier 1, the registry and theming (EFX11–EFX19) ​

#What it showsCommandExpected
D7The same page on the GPU: tier 0 and tier 1xvfb-run -a env -u WAYLAND_DISPLAY -u XDG_RUNTIME_DIR UIG_SHOT=/tmp/fx.png ./apps/ui-gallery/build/ui-gallery --gui --page effects --window-width 60 --window-height 150The five tier-0 panels as in D4, plus a curvature panel whose text and borders visibly bow — rendered to a texture and warped
D8The tier boundary from the other sideD7's capture, "tier 1" section; then D4's terminal outputThe window says "this target renders the bracket to a texture"; the terminal says it paints unaffected. Same widget, same id, two declared answers (EFX12)
D9A theme rebinding built-ins to nothing (EFX16)UIG_EFFECTS=off dub run :ui-gallery -q -- --render --page effectsAll five tier-0 panels identical to none. No view changed — the widgets still name the same ids
D10Every built-in ships both halves of its twin (EFX13)dub test :ui -- -i "ui.effect"builtinsCarryTheirGpuHalf passes: a D function and a GLSL artifact per built-in, each declaring the wrapper's signature
D11A missing effect cannot take a frame down (EFX17)dub test :ui-tui -- -i "tier0EffectLandsInTheTerminal"With no registry bound, the same op stream paints the subtree unaffected instead of failing
D17An effect over raster content — an image is an ordinary leaf inside the bracketD7's capture, "over raster content" section; and D4's terminal outputIn the window the swatch itself is tinted green under phosphor and hue-swept under spectrum; in the terminal the same brackets tint the swatch's cell raster (GLY9), because that is what the cells hold
D18A CRT assembled from the built-ins: tier 0 nested inside tier 1D7's capture, "a CRT · scanlines inside curvature" sectionThe swatch is barrel-warped and its scanlines bow with it — the raster is inside the bracket that warps it, so the composition order is visible, not asserted

Tier 2 and the built-in ids (EFX11, EFX15) ​

#What it showsCommandExpected
D19Tier 2 — a multi-pass effect declared as data — on the GPU, and its declared degradation in a terminalxvfb-run -a env -u WAYLAND_DISPLAY -u XDG_RUNTIME_DIR UIG_SHOT=/tmp/bloom.png ./apps/ui-gallery/build/ui-gallery --gui --page effects --window-width 90 --window-height 150; then dub run :ui-gallery -q -- --render --page effectsIn the PNG, the "tier 2 · reads the layer" panel's text glows — a soft halo following each line, no dotted halftone. In the terminal the same panel is plain, with the note that a cell cannot see its neighbours
D20The built-ins are constants every registry resolvesdub test :ui -- -i "areConstantsInEveryRegistry"Passes: a registry nobody touched resolves Builtin.scanlines … Builtin.bloom through a const pointer, and an app's first effect lands after the last built-in
#What it showsCommandExpected
D12The focus halo outlines what was actually painted (EFX23)xvfb-run -a env -u WAYLAND_DISPLAY -u XDG_RUNTIME_DIR HUE_GUI_SCREENSHOT=/tmp/halo.png HUE_GUI_PICKER= HUE_GUI_CRT=1 ./apps/hue/build/hue view README.md --guiThe halo sits tight on the file picker's border — from the rect the paint site recorded, with no second layout per frame
D13ui-app grew no post-process bracket (EFX22)grep -rni -e postprocess -e postpass libs/ui-app/srcNo matches
D21The CRT is an effect on the frame's root, toggled live (EFX21)./apps/hue/build/hue view README.md --gui, then press F12 twiceF12 curves the whole window into a tube — bloom, scanlines, the phosphor mask and the in-shader pointer — and F12 again returns the flat frame; nothing else in the window changes
D22A CRT capture is reproducible — the effect clock is pinned for it (DBG1)for i in 1 2; do xvfb-run -a env -u WAYLAND_DISPLAY -u XDG_RUNTIME_DIR HUE_GUI_CRT=1 HUE_GUI_SCREENSHOT=/tmp/crt$i.png ./apps/hue/build/hue view README.md --gui; done; cmp /tmp/crt1.png /tmp/crt2.pngcmp prints nothing: two captures of an animated effect are byte-identical
D23The CRT's UI context is harvested from what the frame painted (EFX23)xvfb-run -a env -u WAYLAND_DISPLAY -u XDG_RUNTIME_DIR HUE_GUI_CRT=1 HUE_GUI_SCREENSHOT=/tmp/split.png ./apps/hue/build/hue view . --guiThe divider's seam sits ON the hairline between the tree and the document, and the focused pane's halo hugs what that pane painted

Regression guards worth running ​

| # | What it guards | Command | | --- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | | D14 | The op stays inside its 64-byte budget (IMG1) | dub test :ui -- -i "ui.canvas" | | D15 | The scissor box clamps to its target, not to a sentinel that casts to int.min | dub test :ui-raylib -- -i "scissorBox" | | D16 | Every WidgetKind has a catalogue specimen | dub test :ui-gallery -- -i "primitivesCoversEveryWidgetKind" | | D24 | A component that does not compile says why (enforceAppFor) | dub build --single docs/specs/ui/demos/broken_app.d — the build fails ON PURPOSE: the first line is undefined identifier titel at the typo, then the trace to the assert. With isAppFor the same typo printed only the assert's sentence | | D25 | The gallery's capture hook, on the page that runs shells | xvfb-run -a env -u WAYLAND_DISPLAY -u XDG_RUNTIME_DIR UIG_SHOT=/tmp/term.png ./apps/ui-gallery/build/ui-gallery --gui --page terminal | Exits 0; the PNG shows three shell tabs and the scrolled-back output of seq 1 100 | | D26 | Multi-pass is data, and the CRT is one such record | dub test :ui -- -i "isAMultiPassTier2Effect" and dub test :ui-raylib -- -i "isATier2EffectOnTheRoot" | Both pass |