Files
DarkRoom/tools/manual
dtourolle 2ef971bf37 Fail when the last film stock cannot be reached
The film list bug gave no failure anywhere: the data was right, the
markup compiled, and the list rendered. Two guards now check that the
list can be walked to its end, both by driving input rather than by
reading markup.

tests/film_list_reaches_every_stock.rs runs in CI and needs no display.
It builds the real AppWindow on Slint's testing backend and gives it 28
stocks. It dispatches window events through the same routing a window
uses: popup, Flickables, arbitration. It then checks that the last stock
is on screen, that is, not clipped away:
- after Down past the end, and that Enter chooses it;
- after drags on the list;
- after a run of wheel events with a still pointer;
- after dragging the scrollbar thumb.

Element queries need the Slint compiler's debug tables, which build.rs
emitted only for the `automation` feature. It now emits them for every
debug build too. Release builds, the ones that ship, are unchanged. The
testing backend is a dev-dependency at the same pinned version the
automation feature already uses, so no new crate enters the lockfile.
The test is compiled out of release test runs.

film_reach in tools/manual/scenes.py is the same check on the recording
rig: a real X pointer from xdotool, the release build, and the demo
library. It makes no picture, so it adds nothing to the manual. It runs
with every recording, or alone with `record.sh LIBRARY film_reach`, and
fails the run if the last stock (Ilford HP5 Plus) is out of reach by
the wheel, a drag, the scrollbar or the keys.

Both have to add the popup's position back. The testing backend reports
anything inside a popup relative to the popup, and so does the
automation hook built on it. They take the popup's position from the
Film row and Slint's clamp into the window.
2026-09-26 07:24:46 -04:00
..

tools/manual — the pictures in docs/manual

record.sh drives the desktop build on a private X server and records the scenes in scenes.py into docs/manual/media/:

tools/manual/record.sh /var/tmp/dr-demo/library              # every scene
tools/manual/record.sh /var/tmp/dr-demo/library develop_zoom # one, and what it needs
tools/manual/record.sh --changed /var/tmp/dr-demo/library    # those whose sources moved
tools/manual/record.sh --check                               # the manual and the scenes agree
tools/manual/record.sh --list

Set DR_LIBRARY_SNAPSHOT to a pristine copy of the library: a recording rates, files and merges, and the snapshot is copied over the library first. Each run starts from a fresh profile under DR_HOME.

Controls by name

The binary is built with --features automation, which lets the app answer "where is the control labelled Exposure?" over the Unix socket named by DR_AUTOMATION (ui/dr-ui/src/automation.rs). No other build has the feature, and a build that has it listens only when the variable is set. The names are the accessible labels a screen reader reads, so a scene says click_on('Select@Button') or slide('Exposure', 24) rather than a pixel, and survives a panel that moves. The pointer itself is still xdotool.

DR_HOME=/var/tmp/x tools/manual/drive.py launch /some/folder   # a feature build in DR_BIN
tools/manual/drive.py labels                 # every name on screen
tools/manual/drive.py click-on 'Settings@Button'
tools/manual/drive.py ids canvas             # things with no name: id:canvas-image
tools/manual/drive.py stop

Grid cells are named by file (_MG_8393@ListItem), rating stars 1 star to 5 stars. What a scene cannot name — a point on the photograph, the crop rectangle's corner — it places relative to something it can (drive.photo(fx, fy), id:move-area).

Scenes and the manual

Each scene in scenes.py declares the pictures it makes, as the manual names them, and the globs of the sources that could change them. --check fails when the manual shows a picture no scene makes, or a scene makes one the manual does not show; it reads two files and runs in CI. --changed re-records a scene when one of its sources, or its own code, has changed since the commit that last touched its pictures.

Two things the scripts know that are not obvious: a Slint TouchArea wants a held press, not xdotool's click; and the app is driven on Xvfb rather than the desktop because under XWayland at scale 2 a pointer warp lands at twice the coordinate asked for.