iOS selector click can still tap a stale point after layout shifts the post-open settle does not cover

未关闭
#3,367 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
10/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
typescript
领域
devtools, mobile

调研方向

Start with the selector click path and the post-open settle from #3356, then read src/daemon/interaction-surface-signature.ts, which cannot track target identity across reads. The issue asks for evidence of the shift cases before any design, so first capture a fixture where the target moves between the click's capture and its tap. Done means the click either taps the new location or fails with a typed reason declared in the error taxonomy, with TAP_OUTCOME_NOT_OBSERVED_GAP in packages/contracts/src/interaction-guarantees.ts updated and warm-click p50 on 01-settings.ad unchanged.

由索引模型根据 Issue 内容生成。

描述

backlog bug

Purpose

#3356 settles the next screen read after an iOS open that returns timing.postOpenObservation: "unobservable". Three cases from #3354 are still open. In each one a selector click can tap a stale point and report success:

  • The layout moves between the click's own pre-tap capture and its tap, at any time and not only after an open.
  • The layout moves after an observable open. observable means the tree was readable, not that it was at rest.
  • The post-open read never settles. The click gets postGestureOutcome: unsettled and a warning, then taps anyway.

Evidence

The evidence is the same as #3354: main run 37815426076, where General was at y=319 and the settled list had it at y=406. Nobody has reproduced the shift locally. In 5 live runs of 01-settings.ad on an iOS 27.0 simulator, every read settled before the tap. Collect evidence that these cases happen before choosing a design.

Required behavior

  • When the target's position can't be confirmed at dispatch, the click fails with a typed reason instead of tapping the old point. Declare the reason and its details shape in the error taxonomy.
  • Judging that "the target moved" requires the target's identity across reads. The whole-surface signature comparison (src/daemon/interaction-surface-signature.ts) can't establish it, and it collapses duplicate identities.
  • Do not add a capture or runner query to warm clicks whose layout is already stable.
  • Give any bounded wait a wall-clock deadline, not only a polling budget. Capture cancellation must propagate: abort the capture and wait for it to stop, rather than racing a timer. Today the post-open loop's 1.5 s is a polling budget, and its two reads took 2.55–2.57 s live.
  • A screen that animates constantly must not make a stable target unclickable.
  • Update TAP_OUTCOME_NOT_OBSERVED_GAP in packages/contracts/src/interaction-guarantees.ts.

Completion

  • A fixture where the target moves between the click's capture and its tap. The click either taps the new location or fails with the typed reason.
  • Warm-click p50 on 01-settings.ad, measured before and after the change, does not regress. It was about 1.3 s on the iOS 27.0 simulator.

Rejected so far

  • A runner-side frame check on every click. It would take an estimated 550–800 lines and add a query to every warm click.
  • Settling after every iOS open. The first click would cost about 1.8 s more, with no evidence that observable opens shift, and it still wouldn't cover shifts at other times.
  • Failing whenever the settle times out. A stable target next to an unrelated animation would be refused.

Related: #3354, #3356, #3335.

主要语言
TypeScript
星标
5.2k
派生
359
平均合并
13 小时 23 分钟
30 天内合并 PR
655

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

callstack/agent-device 的其他 Issue

查看 callstack/agent-device 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。