Tell a tap on a photograph from a hand going past

A brush across the grid opened whichever photograph was under it. Travel
was already answered — the Flickable claims the pointer and the press is
cancelled — but a contact that neither travels nor lasts reaches a
TouchArea as an ordinary press and release, and it was landing the user
in develop.

So a finger now has to stay down for `TAP_MIN_MS` before letting go
counts as opening anything. That is the floor under a tap where the 450 ms
`HOLD_DELAY_MS` is the ceiling: below is a graze, between is a tap, above
is a hold that starts a selection. One scale, three gestures.

Only a finger is held to it. A mouse click is a discrete decision made by
a button and is routinely over in thirty milliseconds, so `cell-pressed`
now reports whether a finger did it — the same finger-id convention the
pinch arbitration beside it already uses — and the dwell applies to touch
alone.

A graze still *selects* the cell it landed on, because the press already
did that. That is the right failure mode: something visible and
reversible rather than a silent nothing, and rather than develop.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-29 23:18:07 +02:00
co-authored by Claude Opus 5
parent e40f2bfee9
commit 6d5de21fb7
4 changed files with 132 additions and 5 deletions
+7
View File
@@ -4411,6 +4411,13 @@ pub fn wire<F>(
if coll_for_click.press_was_modified() {
return;
}
// TRACES: FR-UI-4
// And a graze is not a tap. The press has already selected the cell,
// so the user sees what they touched; what they do not get is a
// photograph opened by a hand on its way past.
if coll_for_click.press_was_a_graze() {
return;
}
let path = ctl.paths.borrow().get(i as usize).cloned();
if let Some(path) = path {
// Leave the grid for the develop view. The status bar's