The gesture book runs to several screens inside a card that otherwise
looks complete. Same wrapping as the develop column. The bar is drawn
over the list's right edge, so it overlaps the last few pixels of each
"See it" button.
The help sheet says which move does a thing, and the manual has a
picture of the thing being done, but nothing joined the two: a user
reading "Pinch it with two fingers" had no way from there to the GIF of
it.
A GESTURE tag takes an optional `manual:` field naming a heading of
docs/manual/README.md by its anchor. The scan checks every one against
the anchors the bundled page is rendered with and fails when the manual
has no such heading, so renaming a section cannot leave the sheet
linking to the top of the page; gestures-check carries the same failure
into CI. The anchor goes into gesture_book.rs as a new field, and into
docs/gestures.md as a "See it" link to manual/README.md#anchor. The help
sheet draws a "See it" button beside the title of each gesture that has
one, which opens the bundled manual at that section.
The field is additive: a tag without it is unchanged, and no gesture
carries one yet.
The packages now carry the manual, but nothing in the application opened
it: the help sheet listed gestures and stopped there.
The help sheet gains a Manual button beside Done, and Settings a Manual
row under About beside the version. Both go through dr_ui::manual, which
finds the installed page through dr_plat::system_data_dirs (the package's
share directory on Linux, the executable's directory on Windows), and a
development build also in the checkout it was compiled from. A copy with
no manual says so on the status line rather than doing nothing.
On the desktop the page goes to the system browser. A section is a URL
fragment, and xdg-open's generic mode and Windows' FileProtocolHandler
both turn a file: URL into a path and drop the fragment, so a section is
opened through a one-line redirect page written to the data directory:
the opener gets a plain path, which every opener keeps, and the browser
follows the redirect to index.html#section itself. The launcher behind
the sign-in's open_in_browser is split out so both share it; the https
check stays with the sign-in.
Android has no path to give a browser: an asset is not a file, a copy in
private storage is unreadable to other apps, a file: URI across apps is
refused, and a content: URI leaves the browser resolving every picture
against the provider. So ManualActivity, a WebView reading
file:///android_asset/manual/index.html straight out of the APK, shows
it, started by class name with the section as an extra. JavaScript is
off, links off the page go to the browser, and the theme is day-night so
the page's own light and dark follow the system. A test checks that the
manifest, the Java class and dr_ui agree on the name and the extra.
Rating keys in the grid follow darktable's rule: with the pointer over a
photograph outside the selection, 0-5, P, X and U judge that photograph
alone; over one inside it, the whole selection, as before; off the grid,
the selection. The hover is cleared when the grid scrolls, so a key after
a wheel turn cannot judge whatever used to be under the pointer.
Holding F and tapping digits filters by stars: one digit for exactly
that many, two for everything between them, F alone to show every
rating again. The filter gains a ceiling to do it (`max_rating`, one
BETWEEN in the query). The place record carries it, and a record from an
older build reads as having none. The star chips light across a capped
range and the bar says "2-3★ only" beside them.
The grid also takes Ctrl+E and Ctrl+Shift+E for the selection, Ctrl+V to
paste onto it and Ctrl+A to select all. The "Gestures" button is now
"Help", its sheet "Controls and shortcuts", and F1 opens it.
The document the previous commit generates is for somebody reading the
repository. The person who needs it most is holding a tablet, has just
discovered that a hold does something, and has nowhere to ask what else
does.
So the same scan writes a table the application draws: a "Gestures"
button beside Settings, a sheet with the same scrim and dismissal as the
ones that file and name, and every gesture grouped by where it applies
with its touch, pointer and keyboard routes side by side. Not the `why` —
that is the argument for the design and belongs in the document; on a
phone-sized card it would bury the one line the sheet was opened to read.
The sheet's file knows nothing about what a gesture is. It draws the rows
it is handed, and the rows come from the generated table, because a help
screen with its text typed into it is a second description of one
behaviour — and the second description is always the one that goes stale.
The commit before this deleted a gesture; a hand-kept sheet would still
be describing it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>