Fix CI: add missing CaretGeometrySelector type referenced by tests#322
Conversation
FocusSnapshotResolverSelectionTests referenced a CaretGeometrySelector type that was never committed in #321, breaking the Tests workflow on main. Extract the caret-geometry trust policy out of FocusSnapshotResolver into a pure CaretGeometrySelector in Support/, exposing shouldSearchDeep and select. Wire the resolver through it. Per the tests, primary .derived geometry is now trusted over a deep .exact result and skips the deep AX walk entirely, matching shouldSearchDeep.
| /// The regression these protect against is trusting a descendant rect over the focused input's own | ||
| /// usable rect (or vice versa). Chrome's AXTextArea answers BoundsForRange with a multi-line union | ||
| /// rect — labelled `.derived` but unusable for precise caret placement — while the leaf AXStaticText | ||
| /// holding the active line carries a real `.exact` rect that the deep walk can recover. |
There was a problem hiding this comment.
Class doc contradicts the implementation it describes
Lines 13–15 say Chrome's AXTextArea labels its multi-line union rect .derived, it is "unusable for precise caret placement," and "the deep walk can recover" a real .exact rect from the leaf AXStaticText. But shouldSearchDeep now returns false for .derived, and select prefers primary .derived over a deep .exact (see testPrimaryDerivedWinsOverDeepExact). The protection described in the header is exactly the behavior this PR removes. A Chrome user with a .derived primary union rect will get that unusable rect shipped; the deep walk that recovered the leaf's .exact no longer fires.
Either the doc is stale (Chrome's .derived geometry is now actually usable) and the comment should be updated or removed, or the code regresses Chrome caret placement for editors that still expose a wide union rect under .derived.
Summary
The
Testsworkflow onmainwas red becauseFocusSnapshotResolverSelectionTests(added in #321) referenced aCaretGeometrySelectortype that was never committed —cannot find 'CaretGeometrySelector' in scope. This adds that type as a pure helper inSupport/and wiresFocusSnapshotResolverthrough it, removing the now-duplicated privateselectCaretGeometry/SelectedCaretGeometry.The extracted policy also reflects the behavior the tests encode: primary
.derivedcaret geometry is now trusted over a deep.exactresult and skips the deep AX-tree walk entirely (consistent withshouldSearchDeepreturningfalsefor.derived).Validation
xcodegen generatere-run; the only project drift is the newCaretGeometrySelector.swiftsource reference.Linked issues
Refs #321
Risk / rollout notes
.derivedcaret geometry now wins over deep.exactand no longer triggers the deep AX walk. This trusts the focused input's own rect for.derived-quality geometry rather than escaping to a descendant leaf. Matches the trust policy asserted by the new tests.Cotabby.xcodeproj/project.pbxprojregenerated to register the new source file.Greptile Summary
This PR fixes a broken CI build by adding the missing
CaretGeometrySelectortype that the tests added in #321 referenced but was never committed. As a side effect it refactorsFocusSnapshotResolver's privateselectCaretGeometry/SelectedCaretGeometrypair into the new publicCaretGeometrySelectorenum, and changes the caret-geometry trust policy so that a primary.derivedresult is now trusted and the deep AX-tree walk is skipped for it.CaretGeometrySelector.swift(new): pure, testable enum containingshouldSearchDeepandselect;.derivedprimary geometry is now treated as trustworthy, reversing the old precedence where deep.exactcould override primary.derived.FocusSnapshotResolver.swift: removes the old privateSelectedCaretGeometrystruct andselectCaretGeometryhelper, delegates both the search-deep decision and the geometry-selection precedence toCaretGeometrySelector.project.pbxproj: registers the new source file in the Xcode build system.Confidence Score: 3/5
The refactor is structurally clean but ships an intentional trust-policy change whose correctness for real Chrome sessions is not validated by the new unit tests.
The new
CaretGeometrySelectorclass doc explicitly states that Chrome's AXTextArea labels a multi-line union rect.derivedand it is "unusable for precise caret placement," then says the deep walk can recover a real.exactfrom the leaf. YetshouldSearchDeepnow returnsfalsefor.derivedandselectships the primary.derivedover any deep.exact. If Chrome still exposes that union rect as.derived, caret placement in web editors breaks silently — no integration-level test covers this path and the unit tests use synthetic coordinates that cannot distinguish a precise caret rect from a broad union rect.CaretGeometrySelector.swift — its own header describes the Chrome scenario that the implementation no longer handles; whether that is stale documentation or a latent regression needs confirmation against a real Chromium editor.
Important Files Changed
.derived-is-unusable scenario but the implementation no longer guards against it —shouldSearchDeepreturns false for.derivedandselecttrusts it over a deep.exact.selectCaretGeometry/SelectedCaretGeometryremoved and delegated toCaretGeometrySelector; the call sites and surrounding throttle logic look correct, but inherit the behavior change in the selector.CaretGeometrySelector.swiftin both the file-reference and build-file sections; looks correct and complete.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[resolveSnapshot called] --> B[Build primary candidate\ncaretRect + caretQuality] B --> C{CaretGeometrySelector\n.shouldSearchDeep?} C -- primaryRect nil\nor quality .estimated/nil --> D[Run deepWalkThrottle\nresolveDeepGeometrySource BFS\nup to ~200 AX nodes] C -- quality .exact or .derived --> E[deepResult = nil\nskip BFS entirely] D --> F[CaretGeometrySelector.select] E --> F F --> G{primary .exact?} G -- yes --> H[Ship primary .exact] G -- no --> I{primary .derived?} I -- yes --> J[Ship primary .derived\ndeepResult ignored] I -- no --> K{deepResult present?} K -- yes --> L[Ship deep result\nany quality] K -- no --> M{primary rect present?} M -- yes --> N[Ship primary fallback\n.estimated quality] M -- no --> O[Return nil →\nunsupported snapshot]Reviews (1): Last reviewed commit: "Fix CI: add CaretGeometrySelector type r..." | Re-trigger Greptile