Repository navigation
Conversation
startCompositorTrace keeps every Display::FrameDisplayed in the browser, and those events carry no page identity: with a second page animating, a stall inside the block passed busyWindowProof with presented, crediting the other page's frames. It now throws when another page is open as it starts or stops, and says the record is browser-wide (JSDoc and README). Negative control: another animating page makes it refuse to start, and a page opened mid-trace makes stop() refuse.
A bare relative ASTRYX_WEBKIT_SHADER_CACHE was mounted as a named volume instead of a host directory, and an empty one made mkdirSync throw. The script now resolves a set value with path.resolve and falls back to the default cache directory on an empty one.
… path) into the recorder stand-down # Conflicts: # internal/interaction-harness/src/harness.interaction.browser.spec.ts
…ce; await it before the counted window The README, waitForRest's JSDoc and traceRendering's JSDoc said a traced waitForRest reads no style. Its one read of the element's animations, as it is called, restyles the element when an animation is already running there (2 Layouts and 2 style recalculations in the anchored fixture, 200 ms into its animation). They now say so and tell a proof to await it right after the action that starts the motion, before the window it counts.
Under Reduce Motion, detaching mid-dip landed the waiting move in the model at the end of the task, but with no element attached the landing wrote nothing, so a call that owns its opacity left its dip's low opacity inline on that node: attaching the same node again in a later task (a Suspense or Activity reveal) showed it at opacity 0. The unmount's landing now writes to the node just detached, as dispose() does to its element. The test fails on the previous head. (Found on meta#8067; fixed here because meta#8056, which carries the planner, is approved at its exact head.)
…element support
… against its span In WebKit the rAF negative control could read "1/1 moved": one frame from before the block arrived 45 ms into it, and the moved criterion divided by the delivered frames. A part that delivered fewer than minJudgedFrames frames is now judged against its span, as one that delivered none was (busy.test.ts case; it fails on the previous rule). The README and the self-test header now say only the busy-main-thread proof carries a negative control beside its positive check.
…into n8548 # Conflicts: # internal/interaction-harness/README.md
The lock moved to utils/selectionLock.ts with the shared input stream, and stacks based below that move import it from gestures/selectionLock.ts; a tree carrying both failed to typecheck. The case imports the old path and expects the utils module's functions. Fails on this head.
…rom utils
A one-line transition re-export at gestures/selectionLock.ts keeps
`import {lockSelection} from '../gestures/selectionLock'` working for the
stacks based below the move to utils, so a tree that carries both
typechecks. Remove it once they have moved up.
…line) as a dependency
A watcher already adds nothing to the derived touch-action, and manageStyle is per element, so attaching one with manageStyle: false beside a claiming recognizer switched off that recognizer's touch-action (spec:AST-094 FR18). The README now says a watcher adds nothing instead. Co-authored-by: Christopher Chedeau <vjeuxx@gmail.com>
…l, straight or diagonal, and not before spec:AST-094 FR20's verification names a finger moved 9 px and 10 px straight, and (7, 7) and (8, 8) diagonally: a scroll above the touch takes it only once the finger has travelled 10 px from where it landed. The host already measures that distance; these cases pin the boundary.
…g running Landing a waiting Reduce Motion move on the node just detached rebuilt every channel the landing touched there, so an axis still moving (a coast on y while x waited in a dip) was baked onto the detached node again and promoted it, leaving an animation, timers and will-change behind. After the landing, the unmount now cancels what runs, clears the retire timers and demotes, before the target goes back to none. The test fails on the previous head.
…handlers type UseLongPressHandlers.start takes a point only again, as released: the per-press tolerance useMenuPress's trigger chooses as its press starts lives on the internal useLongPressDetector and LongPressDetectorHandlers, which the hooks entry does not export. useLongPress returns the same detector, typed as before.
|
Posted by Cindy's agent on her behalf: closed and reopened only to restart this PR's CI on the current workflow after tonight's queue-wide cancel; nothing in the PR changed. |
Main merged meta#8045 and meta#8046. The one conflict is utils/pressFeedback.ts: it takes main's merged meta#8046 text (the finger and button slots, the mouse and key press) and keeps this pull request's own additions, the one writer of the press attribute (writePress, paintPress, readPressPaint) and the header line naming them.
# Conflicts: # internal/interaction-harness/README.md # internal/interaction-harness/src/busy.test.ts # internal/interaction-harness/src/busy.ts # internal/interaction-harness/src/frames.ts # internal/interaction-harness/src/harness.interaction.browser.spec.ts
Main's button slot, merged with meta#8046, ends a press's release at once when the next press starts, by clearing the press attribute directly. On a row another painter holds, that clear erased the hold, which this pull request's one writer refuses. A mouse press on a held row, released, then a press elsewhere must leave the row held. Fails until the early end goes through the one writer.
finish() writes none through writePress, as this pull request's controller paints, so a held row stays its owner's when the next press ends a release early, under the finger and the button slots alike.
Both upstream heads are folded onto main 70ea859 (her meta#8045 frame evidence and meta#8046 coarse press): meta#8446 takes main's harness files, and meta#8073 carries the press controller onto meta#8046's slots. meta#8076 has no change of its own in either set of files, so the merge takes theirs with no hand resolution, and meta#8076 is clean against main again.
# Conflicts: # internal/interaction-harness/README.md # internal/interaction-harness/src/busy.test.ts # internal/interaction-harness/src/busy.ts # internal/interaction-harness/src/frames.ts # internal/interaction-harness/src/harness.interaction.browser.spec.ts # packages/core/src/utils/pressFeedback.ts
meta#8076's new head carries main 70ea859 with meta#8073's writer of the press attribute on main's press controller, and its README names both writers. utils/pressFeedback.ts keeps that controller with this line's own changes on it: the pointer, drag, scroll and visibility listeners through the shared input stream (meta#8356) and touchcancel only while the primary pointer is coarse (meta#8270); the key path stays at the window's bubble phase, so a Space press the page cancels paints nothing. usePressTracker stays in its own module, one tracker for a component's life (meta#8315), so meta#8073's rebuilt-tracker hook and its test are not taken. The harness files are meta#8076's.
…s, and the action-group tracker writes its own The header and writePress called it the one writer of the press attribute, but main's action-group tracker writes its groups' presses itself. They now say what holds, as meta#8076's gestures README does.
…he press attribute The release note said every press painter writes data-astryx-press through one internal writer, but the action-group tracker (hooks/actionGroupTracker.ts) writes its groups' presses itself, as the gestures README and utils/pressFeedback.ts already say. The note now says paintPress writes every press it tracks and the action-group tracker writes its own.
…tion to its tracker meta#8046 made the controller paint a mouse press itself where the primary pointer is coarse (a tablet with a trackpad). On an action its group tracks (family:action-groups), the group's tracker paints that press, so the controller must paint nothing there, as it already does for a finger; it paints the press, then turns the tracker's paint to 'fading' at the release. A Space press on the same action still paints: the group tracks pointers only (guard).
… its tracker Where the primary pointer is coarse the controller paints a mouse press itself (meta#8046). It now skips an action a group's tracker paints for a pointer's press, a mouse's included, as it already did for a finger, so the two never write the press attribute over each other. A Space press on the action still paints: the group tracks pointers only.
There was a problem hiding this comment.
Changes requested: the press-group skip itself matches the action-group spec now on main (family:action-groups FR2, landed with #8622), but against main this pull request also carries the whole open #8360/#8076 stack, 26,783 authored lines beside its own 139. Please retarget it onto main once #8360 and #8076 land, so it carries only its three files. Separately, the stack conflicts with the current touch spec in three places that are best fixed in those pull requests:
- The gesture host attaches only where the primary pointer is coarse, while AST-094 FR19 and FR43 and the runtime record's INV13 now require it to attach for every pointer.
- A finger held on a DropdownMenu trigger keeps a 10 px drift under a fine primary pointer, while the useMenuPress record's FR9 applies AST-094 FR29's allowance under every primary pointer.
PressTrackeris a class, while INV13 keeps classes to the recognizer family.
The earlier findings about the fine-pointer finger press and the usePressTracker README are fixed at this head.
[Automated review]
| * | ||
| * ONLY WHERE THE PRIMARY POINTER IS COARSE | ||
| * | ||
| * - Recognizers attach, and the host registers listeners, only while the |
There was a problem hiding this comment.
spec:AST-094 FR19 now reads "Recognizers attach for every pointer, with FR43's exceptions", and architecture:react-component-runtime INV13 says the host attaches "with no touch-only query". Installing only while the primary pointer is coarse (and the warning at :1326-1338) contradicts both. This belongs in #8076/#8360 rather than here.
| * pointer is coarse; where it is fine, the released behavior's tolerance | ||
| * (useMenuPress FR9), the long press's own. Read when the press starts. | ||
| */ | ||
| function triggerTolerance(): LongPressTolerance { |
There was a problem hiding this comment.
module:DropdownMenu/useMenuPress FR9 puts the trigger under spec:AST-094 FR29 "under every primary pointer", so a finger on a touchscreen laptop should get the same 13 px drift as on a phone, not the long press's 10 px. Dropping the pointer read also removes the menus' coarsePointer import.
| return tap.numberOfTapsRequired === 1 && tap.numberOfTouchesRequired === 1; | ||
| } | ||
|
|
||
| export class PressTracker implements TouchConsumer { |
There was a problem hiding this comment.
architecture:react-component-runtime INV13 keeps classes to the recognizer family (its base, the arena and the host), and its verification fails "a class outside the recognizer family". A createPressTracker factory would conform.
Review this PR alone: vjeux/astryx@uikit/f2-click-guard...uikit/c01-press-group-skip
Maintainer impact
Part of the UIKit-parity work: in a group of sibling actions (an alert's buttons, a button group, a toggle group) you can press one and slide to another, as on iOS (
family:action-groups, from #8622). The group's own tracker paints the press on the action under the pointer. The page-wide press controller paints the same buttons, so the two erase each other: the controller's release fade wipes the group's highlight, and the button you started on stays lit beside the one you slid to.Intended invariant
One painter per press. The controller already calls itself the one writer of the press attribute; a group takes that role only for the actions it tracks.
Change
What led to it: building the group tracking for AlertDialog and ButtonGroup showed the double paint.
data-astryx-press-group-item), and the controller paints nothing on a marked action. The mark is there before the first press, and the group can use the same attribute to find its actions.The controller still records the touch on a marked action, so a scroll it starts still brakes the next touch. Where the primary pointer is coarse the controller also paints a mouse press itself (#8046); on a marked action it leaves that to the group too, while a Space press, which the group doesn't track, still paints. No component renders the marker yet: nothing changes until each group adopts it (#8083, #8657, #8660).
Evidence
packages/core/src/utils/pressFeedback.test.ts, six new cases (below).Scope
utils/pressFeedback.tsis internal: it is not on a published entry point.Testing
Nothing to check by hand yet: no component carries the marker.
What was run: six new unit tests. The controller paints nothing on a marked action and leaves the group's paint alone, for a finger and for a mouse on a touch-first device; those fail without this change. It still paints an unmarked member, which fails if the skip checks group membership instead of the mark, and a Space press on a marked action. It still records the touch for the scroll brake, which fails if the skip comes first. Typecheck, lint, the core unit suite and the press accessibility tests pass locally; GitHub Actions isn't running on this repository right now.
Stack: on #8360, which carries #8076. The adoptions (#8083, #8657, #8660) stack on this pull request.