Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 79927d64201a2baed8ee1604f9c46cc4aa3c14c2
      
https://github.com/WebKit/WebKit/commit/79927d64201a2baed8ee1604f9c46cc4aa3c14c2
  Author: Tyler Wilcock <[email protected]>
  Date:   2026-07-01 (Wed, 01 Jul 2026)

  Changed paths:
    A 
LayoutTests/accessibility/ios-simulator/local-frame-content-scroll-geometry-expected.txt
    A 
LayoutTests/accessibility/ios-simulator/local-frame-content-scroll-geometry.html
    A 
LayoutTests/accessibility/ios-simulator/local-frame-root-scroll-geometry-expected.txt
    A 
LayoutTests/accessibility/ios-simulator/local-frame-root-scroll-geometry.html
    A LayoutTests/accessibility/resources/scrollable-iframe-content.html
    M Source/WebCore/accessibility/AXObjectCache.cpp
    M Source/WebCore/accessibility/AXObjectCache.h
    M Source/WebCore/accessibility/AccessibilityObject.cpp
    M Source/WebCore/accessibility/AccessibilityScrollView.cpp
    M Source/WebCore/accessibility/AccessibilityScrollView.h

  Log Message:
  -----------
  AX: After ACCESSIBILITY_LOCAL_FRAME, VoiceOver can read stale element 
geometry after a frame scrolls its own content
https://bugs.webkit.org/show_bug.cgi?id=318158
rdar://179106823

Reviewed by Dominic Mazzoni.

With ENABLE(ACCESSIBILITY_LOCAL_FRAME), local frames compose an element's screen
position the same way remote frames do: a cached per-frame 
AXFrameGeometry.screenPosition
(the frame's content origin on screen, with the frame's scroll baked in when it 
was
sampled) plus the element's content-space rect. That cached geometry is 
refreshed only
by an asynchronous re-push, so when a frame scrolls its own content, e.g. a 
horizontal
CSS-column page-turn in Apple Books, the baked-in scroll goes stale until the 
re-push
lands. An assistive technology reading in that window gets a mispositioned 
rect, so
paginated content lands off the viewport and VoiceOver cannot reach it.

Stop depending on the re-push for a frame's own scroll. In convertFrameToSpace, 
read the
current scroll live (we are on the main thread here), undo the stale sampled 
scroll baked
into screenPosition, and re-apply the current scroll. In steady state the two 
are equal
and this is a no-op. During the race it keeps the read correct. To carry the 
sampled scroll
to the reader, capture it in AXObjectCache::setFrameGeometry and expose it via
frameViewOriginScrollPosition().

Also fix the related first-access case: when accessibility turns on, 
frameGeometry()
returned the default {0,0} origin while it kicked off the asynchronous request, 
so an AT
that walks and caches frames immediately would receive mispositioned rects. 
Compute the
screen position synchronously on that first main-thread access instead, falling 
back to
the asynchronous request only when it can't be computed in-process.

* 
LayoutTests/accessibility/ios-simulator/local-frame-content-scroll-geometry-expected.txt:
 Added.
* 
LayoutTests/accessibility/ios-simulator/local-frame-content-scroll-geometry.html:
 Added.
* LayoutTests/accessibility/resources/scrollable-iframe-content.html: Added.
* Source/WebCore/accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::setFrameGeometry):
* Source/WebCore/accessibility/AXObjectCache.h:
* Source/WebCore/accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::convertFrameToSpace const):
* Source/WebCore/accessibility/AccessibilityScrollView.cpp:
(WebCore::AccessibilityScrollView::frameGeometry const):
(WebCore::AccessibilityScrollView::frameViewOriginScrollPosition const):
* Source/WebCore/accessibility/AccessibilityScrollView.h:

Canonical link: https://commits.webkit.org/316341@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to