Skip to content

spec(AST-094): only a finger's first uncancelable move can hand it to the browser (FR20) - #8456

Merged
cixzhang merged 3 commits into
mainfrom
spec/ast094-uncancelable-touchmove
Oct 31, 2026
Merged

cixzhang merged 3 commits into
mainfrom
spec/ast094-uncancelable-touchmove

Conversation

@cixzhang

@cixzhang cixzhang commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Decision

spec:AST-094 FR20: only a finger's first uncancelable touchmove counts as the browser taking the touch, and only when the browser could scroll along the finger's main axis. The main axis is the one the finger has moved farther along since touch-down, horizontal on a tie; the browser could scroll along it when a scroller under the touch has room that way and every touch-action between them allows that pan (FR18). Later uncancelable moves of that finger never count. pointercancel and a native scroll past the 10 px take distance count as before. One verification row covers a horizontal drag under pan-y, a vertical drag under pan-y over a scroller with room, and a vertical drag where no scroller has room.

Why

Chromium stops letting a page cancel touchmoves after the first one it does not consume, even on an axis touch-action forbids (a horizontal drag under pan-y). Counting every uncancelable touchmove therefore drops every sideways swipe inside a vertically scrolling page (a carousel, a swipe row) on Android before it reaches its 10 px start. A real browser pan still reports through pointercancel or the scroll. The gesture host in #8071 already judges the first uncancelable move this way. Credit: @vjeux measured the Chromium behavior and proposed the rule.

Existing authority searched

Rejected alternatives

  • Counting every uncancelable touchmove.

Writing rubric results

  • R1 narration: none.
  • R2 research in the record: none; the Chromium measurement stays in this description.
  • R3 evidence naming a change: none.
  • R4 rejected alternatives over one line or outside a decision: none.
  • R5 pull request or issue references remaining: none.
  • R6 ruled open questions still listing options: none.

Scope

  • This PR contains specification records only: one FR20 sentence and one verification row.
  • It records observable behavior and preserves equivalent internal implementations.
  • Public text contains no internal context.

Validation

  • pnpm check:knowledge
  • Prettier

@vercel

vercel Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Oct 31, 2026 12:22am UTC

Request Review

@astracat-bot

astracat-bot Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Oct 31, 2026, 12:22 AM UTC

@github-actions github-actions Bot added the needs:spec-owner-review Current knowledge records await owner approval label Oct 25, 2026
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 25, 2026
@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

View Storybook for this PR · View Sandbox for this PR

Current run: The current change has no visual or preview-producing scope. Visual checks are not applicable; preview links are not shown.


Generated by PR Enrichment workflow | View current CI run

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This spec change is waiting on an engineering owner's decision: it narrows a current requirement (spec:AST-094 FR20, which today counts every uncancelable touchmove as the browser taking the touch), and no owner has approved this head yet. Please rebase and address the points below in one commit first, because a new commit invalidates an earlier approval; then any engineering owner records the decision by commenting /approve-spec <full head SHA> on the pull request, and as the author you may do so yourself if you are an engineering owner.

  • The Verification table now conflicts with main, where the FR7, FR8 row gained a design:reduced-motion DR2 exception; keep that text, and label the new row FR20 so Prettier stops re-padding the whole table.
  • The "Proposed; pending owner decision" prefix in FR20 and the "(proposed)" row label would land in a current record on approval (architecture:knowledge-contracts INV10), so state the narrowed rule in the present tense and keep the status in the description.
  • The decision should also settle whether "first" means the touch's first uncancelable touchmove, and whether "could pan" means the element's touch-action alone or a scroller with room on that axis, which is how the gesture host in #8072 judges it.

[Automated review]

`touchmove`, or a native scroll under the touch MUST count as the browser
taking the touch: possible recognizers that share it fail, active ones are
cancelled, and the view's press is cancelled without a release. A recognizer that never claims (a watcher) registers only passive
cancelled, and the view's press is cancelled without a release. **Proposed; pending owner decision:** an uncancelable `touchmove` counts

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This status label would stay in the record once an engineering owner approves this exact head, since approval binds to the head and the gate enables squash auto-merge for spec-only pull requests after it. Please state the narrowed rule in the present tense, for example folded into FR20's first sentence, and keep "pending owner decision" in the pull request description (architecture:knowledge-contracts INV10; R1 in docs/contributing/spec-writing.md).

Comment on lines +264 to +265
only when it is the touch's first and the browser could pan along the
finger's axis under the element's `touch-action`. A recognizer that never claims (a watcher) registers only passive

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two readings to settle before approval: "the touch's first" can mean the touch's first touchmove (cancelable in the Chromium sequence the description gives, so the clause would never fire) or its first uncancelable one; and "could pan ... under the element's touch-action" reads the element's own value, while the gesture host in #8072 asks whether a scroller under the touch still has room on that axis.

| FR14 | Browser tests of a sheet over a scrolled list | scrolled and at its top | a midway handoff fails |
| FR15–FR17 | Recognizer unit tests on synthetic streams with explicit timestamps | exclusive, simultaneous, require-to-fail, nested; a blocked main thread; a pan at 10 pt per axis | a wrong winner, a late deadline, or a translation that keeps the hysteresis fails |
| FR18–FR22 | Browser tests with real touch input | per-axis pans beside native scrolling, page zoom, cancelled touches, clicks after taps, keyboard activation, a modal scroll lock, a control that keeps its press through a drag | a ghost click, a blocked scroll or zoom, or a cancelled unowned touchmove outside FR19's two exceptions fails |
| FR20 uncancelable `touchmove` (proposed) | Browser tests with real touch input in Chromium phone emulation (`spec:AST-013` FR10) | a horizontal drag under `pan-y`; a vertical drag under `pan-y` | a horizontal drag under `pan-y` cancelled, or a vertical drag under `pan-y` not counted as the browser taking the touch, fails |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 40-character label re-pads all 23 lines of the table, which now conflicts with main, where the FR7, FR8 row gained a design:reduced-motion DR2 exception. Labelling the row FR20 keeps the 15-character column, so Prettier adds only this line; when rebasing, keep main's FR7, FR8 text.

…ly when the browser could pan along the finger (FR20)

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This spec change is waiting on an engineering owner's decision: it intentionally narrows a current requirement (spec:AST-094 FR20, which today counts every uncancelable touchmove as the browser taking the touch), and no engineering owner has approved this head. Before that approval, please state the narrowed rule in the present tense and drop the "Proposed; pending owner decision" prefix in FR20 and the "(proposed)" row label, because approving this exact head would land that status text in a current record (architecture:knowledge-contracts INV10), and a new commit invalidates an earlier approval. Then any engineering owner records the decision by commenting /approve-spec <full head SHA> on the pull request, and as the author you may do so yourself if you are an engineering owner.

  • The decision should settle whether "first" means the touch's first uncancelable touchmove, how a diagonal move picks "the finger's axis", and whether "could pan" means the element's own touch-action or a scroller under the touch with room on that axis, which is how the gesture host in #8072 judges it.
  • Labelling the new row FR20 keeps the table's 15-character first column, so the row adds one line instead of re-padding the whole table.

[Automated review]

@cixzhang cixzhang changed the title spec(AST-094): proposed: an uncancelable touchmove takes the touch only when the browser could pan along the finger spec(AST-094): only a finger's first uncancelable move can hand it to the browser (FR20) Oct 31, 2026
@cixzhang

Copy link
Copy Markdown
Contributor Author

/approve-spec 08003ec

@github-actions github-actions Bot removed the needs:spec-owner-review Current knowledge records await owner approval label Oct 31, 2026

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This FR20 change is ready from the review side: an engineering owner approved this exact head, and the narrowed rule reads consistently with FR2, FR18, FR19 and DEC-8, with no defects left to fix. One optional tightening: the new verification row lists a vertical drag where no scroller has room but gives it no failure, so an implementation that judged by touch-action alone and ignored scroller room would still pass it; a clause failing that drag's first uncancelable move when it is counted would close the gap. Any further edit to the spec text needs a fresh /approve-spec on the new head.

[Automated review]

| FR14 | Browser tests of a sheet over a scrolled list | scrolled and at its top | a midway handoff fails |
| FR15–FR17 | Recognizer unit tests on synthetic streams with explicit timestamps | exclusive, simultaneous, require-to-fail, nested; a watcher beside a claiming winner; a blocked main thread; a pan at 10 pt per axis | a wrong winner, a late deadline, or a translation that keeps the hysteresis, or a watcher failed or cancelled by a claiming winner fails |
| FR18–FR22 | Browser tests with real touch input (`spec:AST-013` FR10) | per-axis pans beside native scrolling, page zoom, cancelled touches, clicks after taps, keyboard activation, a modal scroll lock, a control that keeps its press through a drag; a still finger with sub-pixel jitter over a scroll view; a finger moved 9 px and 10 px straight, and (7, 7) and (8, 8) diagonally; a recognizer on an element whose author `touch-action` is narrower, including one without `pinch-zoom`; a screen-edge pan landing at 40 px and at 41 px from the edge, at 14 px and 15 px of travel, and a horizontal scroll that starts outside the band; a screen-edge pan on an element within the band, and on one that reaches beyond it; a sheet's pull from a list at its top, and from a list scrolled away from its top | a ghost click, a scroll or zoom blocked other than by the author's `touch-action`, or a cancelled unowned touchmove outside FR19's three exceptions, a tap cancelled by sub-pixel movement or by under 10 px of travel, a scroll that does not take the touch at 10 px, or a derived `touch-action` wider than the author's, a screen-edge pan that claims outside its band or before 15 px on an element within the band, or has not claimed at 15 px, or an author scroll outside the band that is blocked, a band claim of `pan-x` on an element that reaches beyond the band, or a 15 px start there, or a scroll-edge pan that cancels a move a scroller could scroll, or begins before 10 pt, fails |
| FR20 | Browser tests with real touch input in Chromium phone emulation (`spec:AST-013` FR10) | a horizontal drag under `pan-y`; a vertical drag under `pan-y` over a scroller with room; a vertical drag where no scroller has room | a horizontal drag under `pan-y` counted as the browser taking the touch, a vertical one over a scroller with room not counted, or a later uncancelable move counted, fails |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: this row lists "a vertical drag where no scroller has room" but no failure covers it, so an implementation that judges by touch-action alone and ignores scroller room would still pass. A clause such as "or the first uncancelable move of a vertical drag where no scroller has room counted" would make that state bite.

@cixzhang
cixzhang merged commit bb46e36 into main Oct 31, 2026
56 checks passed

This branch was successfully deployed

1 active deployment
Preview — 08003ec9 Deployed Oct 31, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant