Repository navigation
fix(daemon): run find focus through the shared touch-point decisions - #4223
Conversation
The find focus seam dispatches its own point instead of re-entering the interaction leaf, so it skipped the touch-point decision the acting paths run. A match fully tiled by interactive children now refuses before dispatch, and a child owning the center moves the aim to free parent space. Missing or zero-area rects get the typed invalid-bounds refusal. Move resolveNodeTouchPoint to @agent-device/selectors/node-touch-point so the daemon and command-runtime share one owner, and close the parentOwnedTouchPoint cell of the find-focus-dispatch guarantee row. Refs callstack#3734
The package-boundaries enumeration lists every selectors subpath, so the new export has to be declared for the R11 layering rule to accept it.
The offscreen and nonHittable waiver reasons still said the seam dispatches a rect center.
The touch-point rule treats a nested text field as a competitor to avoid, so a match wrapping a field reported focus success beside the field and the typed text then went wherever the focus already was. A sole enabled, visible field now becomes the target, with the same touch-point, covered and keyboard checks. Several fields refuse with AMBIGUOUS_MATCH and the field candidates. Refs callstack#3734
A disabled field promotes to its parent on iOS, and the parent's other field then counted as the sole one, so find type wrote into a field the locator never named. The located field now decides first: an enabled one stays the target and a disabled one refuses with target_disabled, as does a match holding only disabled fields. Count only outermost on-screen typed fields, so a hosted text field, a scrolled-away field and an untyped child no longer change the target. The rule moves to the find description so MCP clients see it, and it names web text boxes as unrecognized. Refs callstack#3734
The disabled check only read the located node, so a same-rect wrapper over a disabled field was still focused, and a label inside one was promoted past it to an enabled sibling. find type then wrote into another field and reported success. The field decision now walks from the located node to the promoted one, and the nearest field on that path is the named field. The find help, selector docs and nonHittable waiver now state that a named text field stays the target. Refs callstack#3734
There was a problem hiding this comment.
All reported issues were addressed across 17 files
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
A field with no usable bounds counted as on-screen, so it could take the focus or turn a single field into an ambiguity before the touch point could reject it. A password fact on an unrecognized type was ignored, so focus went to the container instead. Say in the help and docs that a named field wins over its neighbours and that target_disabled is a reason, and record why the nested-field refusal follows find's refusal contract for printed refs. Refs callstack#3734
There was a problem hiding this comment.
All reported issues were addressed across 8 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 1 file (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
|
At 5c8f01c, the code looks good. Not blocking, take or leave: the covered bullet in selectors.md names The Android Smoke failure is at the step "open deterministic fixture route with system IME", where |
|
At 2e1ba8a, the code looks good. The new commit only changes one line in |
Summary
find focusandfind typedispatch their own point, so they skipped the touch-point decisions the acting paths run. They could tap the middle of a container and report success.Now they share those decisions. A match holding one text field aims at it. Several fields refuse with
AMBIGUOUS_MATCHand name them. A field the locator named stays the target, and a disabled one refuses withtarget_disabled.Touches 18 files. Scope expansion: the touch-point module moves to a new
@agent-device/selectors/node-touch-pointsubpath. Refs #3734: the other waived guarantee cells remain.Validation
Tested
2e1ba8a6d.pnpm check:affected --run --head: 41 passed, 25 skipped,exactCommit=true. Skipped includesunit-ci,coverage, Swift runners and replay lanes; CI owns those.Live at
5daff16a6, not rerun since; iPhone 17 simulator, Contacts new-contact form. Comparison: #4219's branch, with base035c2b6ca's find code.find role=table focus: comparison taps (201, 507), reports success, and First name keeps focus; head refuses, naming 3 fields.find value="Last name" type Lovelace: lands in Last name, 3/3 on each.Risks:
textbox/searchboxare not recognized as text fields; the docs say so.find role=cell focus --firsttaps the Ringtone row on both builds, because--firstfollows ranking.🤖 Generated with Claude Code