Skip to content

Fix iOS accessibility reading bounds and coordinates - #629

Open
at-wr wants to merge 2 commits into
migueldeicaza:mainfrom
at-wr:fix/ios-accessibility-reading-content-upstream
Open

Fix iOS accessibility reading bounds and coordinates#629
at-wr wants to merge 2 commits into
migueldeicaza:mainfrom
at-wr:fix/ios-accessibility-reading-content-upstream

Conversation

@at-wr

@at-wr at-wr commented Aug 11, 2026

Copy link
Copy Markdown

Summary

  • return NSNotFound/nil/.zero for invalid reading-content lines instead of indexing outside the terminal buffer
  • clamp the current-page range to visible buffer rows and use the actual final row width
  • convert reading line hit-testing from screen coordinates and report frames in screen coordinates as UIKit requires
  • stop posting layoutChanged on every terminal repaint, which can repeatedly reset VoiceOver focus
  • add platform-neutral boundary tests for line and visible-page calculations

Rationale

Apple documents that accessibilityLineNumber(for:) receives screen coordinates, accessibilityFrame(forLineNumber:) must return screen coordinates, and invalid line numbers return no content. layoutChanged is reserved for actual screen layout changes, not terminal cell updates.

Testing

  • DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift test --filter AccessibilityReadingPolicyTests (5 tests pass on current main and the 1.18.0 backport)
  • strict signed iPadOS 26.5 Simulator build succeeds in the downstream app
  • live loopback SSH audit streamed terminal output, exercised local word selection/copy, and inspected independent primary/secondary reading elements and dynamic VoiceOver custom actions

@at-wr
at-wr marked this pull request as ready for review August 11, 2026 02:16

@migueldeicaza migueldeicaza left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thank you for sending this along!

// UIKit supplies this point in screen coordinates. Converting through
// the scroll view also accounts for its bounds origin/content offset.
let localPoint = convert(point, from: nil)
return AccessibilityReadingPolicy.lineNumber(

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I think that accessibilityLineNumber receives screen coordinates, and the call to convert does it from window coordinates, I think this needs reviewing.

From their docs:

https://developer.apple.com/documentation/uikit/uiaccessibilityreadingcontent/accessibilitylinenumber%28for%3A%29

A point within the bounds of the receiver’s view space, in screen coordinates. That is, a point for which [self pointInside:point withEvent:event] == YES.

The "nil" to convert indicates window coordinates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants