Reworks the README demo (tools/demo, docs/media/demo.mp4).
Same flow (side-by-side windows, bands, stash, overview), now 49 s.
Firefox opens a live DuckDuckGo search; the fake tools/demo/site page is gone.
Ending: back on workspace 1, Firefox fullscreen (Super+Shift+f), hint mode (Super+g), the label of the "Wayland (protocol) - Wikipedia" result is typed and Wikipedia opens.
The compositor runs inside the Docker image with tesseract and AT-SPI; demo-hint-label finds the target label by OCR so the typed label is deterministic despite live content.
record.sh fails on truncated (timeout) recordings and on hosts without an AMD GPU (vulkan-radeon is required for hint scans).
Headless screenshots encode each frame once with BestSpeed PNG and publish latest.png as a hard link: 75 ms to ~38 ms per frame, max 12 to 19 unique frames/s in the video.
Checks: make check, make race, make mocks-check, staticcheck, shellcheck. Wrap-up reviews (Go + demo tooling) done, all findings fixed or explicitly kept.
Known limits: live site content varies between recordings (the script fails loudly if the target result is missing); unique frame rate is still below 30 fps (Go PNG encoder floor).
- `latest.png` shows the current frame; `frames.ffconcat` records frame timing. Every frame is also saved as `frame-NNNNNN.png`, so the directory grows.
10
+
- `latest.png` shows the current frame; `frames.ffconcat` records frame timing. Every frame is also saved as `frame-NNNNNN.png`, so the directory grows. `latest.png` is a hard link to the newest frame, so replace it rather than editing it in place.
11
11
- `--size 640x360,640x360` creates two outputs, arranged left to right,
12
12
for testing `focus-monitor-left/right` and moving columns between outputs.
13
13
- With several outputs, each writes to `<dir>/HEADLESS-<n>/`.
For a GIF, convert `demo.mp4` with ffmpeg's `palettegen` and `paletteuse` filters.
26
26
27
27
### Demo recording
28
-
Run `tools/demo/record.sh` with Go 1.27, rootless Docker and ffmpeg installed.
29
-
It builds an Arch app image and the host compositor, then records the 1080p README demo.
30
-
Apps run in a disposable, offline container; only the headless Wayland socket is mounted.
31
-
A FIFO synchronizes `input.txt` with app launches after container startup.
28
+
Run `tools/demo/record.sh`. It requires Go 1.27, rootless Docker, ffmpeg, network access and an AMD GPU.
29
+
It builds the Arch image (apps, tesseract, AT-SPI) and the compositor binary, then records the 1080p README demo.
30
+
The compositor runs headless inside a disposable container, with the binary and a work directory bind-mounted and `/dev/dri` passed for the GPU.
31
+
The image only carries Mesa's radeon Vulkan driver, and hint scans need the sync files that a hardware driver exports; the script stops early without an AMD render node.
32
+
Firefox opens a live DuckDuckGo page, so the recording needs the network and its content varies.
33
+
A FIFO feeds `input.txt` while the script launches the apps on the same clock.
34
+
The hint step makes Firefox fullscreen and labels the page with `hint`; `hint-click <words>` then types the label of the link that shows those words, found from the scan's dump and an OCR read of the still page (`hint-read`).
35
+
The recording only counts if the compositor stops on the quit key that ends `input.txt`; reaching its `--timeout` first fails the run as truncated.
32
36
Temporary captures are removed by default; set `KEEP_CAPTURE=1` to keep successful runs.
33
37
The recording and poster replace `docs/media/demo.mp4` and `docs/media/demo.png`.
- `latest.png` shows the current frame; `frames.ffconcat` records frame timing. Every frame is also saved as `frame-NNNNNN.png`, so the directory grows.
10
+
- `latest.png` shows the current frame; `frames.ffconcat` records frame timing. Every frame is also saved as `frame-NNNNNN.png`, so the directory grows. `latest.png` is a hard link to the newest frame, so replace it rather than editing it in place.
11
- `--size 640x360,640x360` creates two outputs, arranged left to right,
11
- `--size 640x360,640x360` creates two outputs, arranged left to right,
12
for testing `focus-monitor-left/right` and moving columns between outputs.
12
for testing `focus-monitor-left/right` and moving columns between outputs.
13
- With several outputs, each writes to `<dir>/HEADLESS-<n>/`.
13
- With several outputs, each writes to `<dir>/HEADLESS-<n>/`.
For a GIF, convert `demo.mp4` with ffmpeg's `palettegen` and `paletteuse` filters.
25
For a GIF, convert `demo.mp4` with ffmpeg's `palettegen` and `paletteuse` filters.
26
26
27
### Demo recording
27
### Demo recording
28
-
Run `tools/demo/record.sh` with Go 1.27, rootless Docker and ffmpeg installed.
28
+
Run `tools/demo/record.sh`. It requires Go 1.27, rootless Docker, ffmpeg, network access and an AMD GPU.
29
-
It builds an Arch app image and the host compositor, then records the 1080p README demo.
29
+
It builds the Arch image (apps, tesseract, AT-SPI) and the compositor binary, then records the 1080p README demo.
30
-
Apps run in a disposable, offline container; only the headless Wayland socket is mounted.
30
+
The compositor runs headless inside a disposable container, with the binary and a work directory bind-mounted and `/dev/dri` passed for the GPU.
31
-
A FIFO synchronizes `input.txt` with app launches after container startup.
31
+
The image only carries Mesa's radeon Vulkan driver, and hint scans need the sync files that a hardware driver exports; the script stops early without an AMD render node.
32
+
Firefox opens a live DuckDuckGo page, so the recording needs the network and its content varies.
33
+
A FIFO feeds `input.txt` while the script launches the apps on the same clock.
34
+
The hint step makes Firefox fullscreen and labels the page with `hint`; `hint-click <words>` then types the label of the link that shows those words, found from the scan's dump and an OCR read of the still page (`hint-read`).
35
+
The recording only counts if the compositor stops on the quit key that ends `input.txt`; reaching its `--timeout` first fails the run as truncated.
32
Temporary captures are removed by default; set `KEEP_CAPTURE=1` to keep successful runs.
36
Temporary captures are removed by default; set `KEEP_CAPTURE=1` to keep successful runs.
33
The recording and poster replace `docs/media/demo.mp4` and `docs/media/demo.png`.
37
The recording and poster replace `docs/media/demo.mp4` and `docs/media/demo.png`.
'gsettings set org.xfce.mousepad.preferences.view use-default-monospace-font false; gsettings set org.xfce.mousepad.preferences.view font-name "JetBrainsMono Nerd Font 15"; gsettings set org.xfce.mousepad.preferences.window menubar-visible false; mousepad /home/demo/config'
96
+
# Mousepad runs as demo (it warns about root), with a file-backed
97
+
# GSettings and no session bus (it needs the root-owned bus otherwise).
# Mousepad runs as demo (it warns about root), with a file-backed
82
-
'gsettings set org.xfce.mousepad.preferences.view use-default-monospace-font false; gsettings set org.xfce.mousepad.preferences.view font-name "JetBrainsMono Nerd Font 15"; gsettings set org.xfce.mousepad.preferences.window menubar-visible false; mousepad /home/demo/config'
97
+
# GSettings and no session bus (it needs the root-owned bus otherwise).
<main><header>◈ NEFERWL</header><h1>Your desktop.<br>A little more focused.</h1><p>A Wayland compositor with room for your work.<br>Tile naturally, set things aside, see the whole picture.</p><div class="cards"><section class="card"><b>01 / Performance</b><p>Small, responsive.<br>Built in Go. Made to stay out of your way.</p></section><section class="card"><b>02 / Stash</b><p>Keep tools close.<br>Set aside a window. Bring it back in a keystroke.</p></section><section class="card"><b>03 / Overview</b><p>Find your focus.<br>Every workspace and stashed window, at a glance.</p></section></div><pre># A desktop that flows with you
10
-
layout.max-columns = 2
11
-
layout.overflow = cascade
12
-
animations = on</pre><footer>SUPER + ↑ / ↓ bands · SUPER + S stash · SUPER + O overview</footer></main>
<main><header>◈ NEFERWL</header><h1>Your desktop.<br>A little more focused.</h1><p>A Wayland compositor with room for your work.<br>Tile naturally, set things aside, see the whole picture.</p><div class="cards"><section class="card"><b>01 / Performance</b><p>Small, responsive.<br>Built in Go. Made to stay out of your way.</p></section><section class="card"><b>02 / Stash</b><p>Keep tools close.<br>Set aside a window. Bring it back in a keystroke.</p></section><section class="card"><b>03 / Overview</b><p>Find your focus.<br>Every workspace and stashed window, at a glance.</p></section></div><pre># A desktop that flows with you
10
-
layout.max-columns = 2
11
-
layout.overflow = cascade
12
-
animations = on</pre><footer>SUPER + ↑ / ↓ bands · SUPER + S stash · SUPER + O overview</footer></main>