| Summary: | AX: Press tab to highlight items on a webpage is not working with voiceover enabled | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | WebKit | Reporter: | Nan Wang <n_wang> | ||||||||
| Component: | Accessibility | Assignee: | Nobody <webkit-unassigned> | ||||||||
| Status: | RESOLVED FIXED | ||||||||||
| Severity: | Normal | CC: | aboxhall, apinheiro, cdumez, cfleizach, dbates, dmazzoni, esprehn+autocc, ews-watchlist, jcraig, jdiggs, kangil.han, n_wang, rniwa, samuel_white, webkit-bug-importer, zalan | ||||||||
| Priority: | P2 | Keywords: | InRadar | ||||||||
| Version: | WebKit Nightly Build | ||||||||||
| Hardware: | All | ||||||||||
| OS: | All | ||||||||||
| Attachments: |
|
||||||||||
|
Description
Nan Wang
2018-07-19 15:14:14 PDT
Created attachment 345390 [details]
patch
Comment on attachment 345390 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=345390&action=review > Source/WebCore/dom/Document.cpp:1871 > + } Any style mutation with an associated renderer will trigger a RenderElement::setStyle() call. Even mutations that don't need layout. Consulting StyleDifference in setStyle() might be a better way to get the AX cache updated. Also you may want to limit the performDeferredCacheUpdate() calls to focusable elements since calling AX cache on every repaint could be a performance hit. Comment on attachment 345390 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=345390&action=review >> Source/WebCore/dom/Document.cpp:1871 >> + } > > Any style mutation with an associated renderer will trigger a RenderElement::setStyle() call. Even mutations that don't need layout. Consulting StyleDifference in setStyle() might be a better way to get the AX cache updated. > Also you may want to limit the performDeferredCacheUpdate() calls to focusable elements since calling AX cache on every repaint could be a performance hit. Here we are doing the AX cache update on the document level and it's under the styleUpdate check. Are you saying: 1. frameView.needsLayout() check is not enough, we should use the StyleDifference in renderElement? 2. We should move the AX cache update to a RenderElement level, so for each RenderElement we check and update the cache in setStyle()? I think performDeferredCacheUpdate() is designed as a batch update mechanism. We are calling that in FrameView performPostLayoutTasks(). So I'm looking for some place similar, that indicates the FrameView;s style is resolved. (In reply to Nan Wang from comment #3) > Comment on attachment 345390 [details] > patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=345390&action=review > > >> Source/WebCore/dom/Document.cpp:1871 > >> + } > > > > Any style mutation with an associated renderer will trigger a RenderElement::setStyle() call. Even mutations that don't need layout. Consulting StyleDifference in setStyle() might be a better way to get the AX cache updated. > > Also you may want to limit the performDeferredCacheUpdate() calls to focusable elements since calling AX cache on every repaint could be a performance hit. > > Here we are doing the AX cache update on the document level and it's under > the styleUpdate check. Are you saying: > 1. frameView.needsLayout() check is not enough, we should use the > StyleDifference in renderElement? > 2. We should move the AX cache update to a RenderElement level, so for each > RenderElement we check and update the cache in setStyle()? I think > performDeferredCacheUpdate() is designed as a batch update mechanism. We are > calling that in FrameView performPostLayoutTasks(). So I'm looking for some > place similar, that indicates the FrameView;s style is resolved. Oh right, this is the "perform" and not the "dirtying" part. So who is dirtying the AX tree when non-layout type of mutation happens? I would assume that if AX tree sees that the mutation is not going to trigger layout, it could just issue a timer and update the tree in the next runloop. Comment on attachment 345390 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=345390&action=review >>>> Source/WebCore/dom/Document.cpp:1871 >>>> + } >>> >>> Any style mutation with an associated renderer will trigger a RenderElement::setStyle() call. Even mutations that don't need layout. Consulting StyleDifference in setStyle() might be a better way to get the AX cache updated. >>> Also you may want to limit the performDeferredCacheUpdate() calls to focusable elements since calling AX cache on every repaint could be a performance hit. >> >> Here we are doing the AX cache update on the document level and it's under the styleUpdate check. Are you saying: >> 1. frameView.needsLayout() check is not enough, we should use the StyleDifference in renderElement? >> 2. We should move the AX cache update to a RenderElement level, so for each RenderElement we check and update the cache in setStyle()? I think performDeferredCacheUpdate() is designed as a batch update mechanism. We are calling that in FrameView performPostLayoutTasks(). So I'm looking for some place similar, that indicates the FrameView;s style is resolved. > > Oh right, this is the "perform" and not the "dirtying" part. So who is dirtying the AX tree when non-layout type of mutation happens? I would assume that if AX tree sees that the mutation is not going to trigger layout, it could just issue a timer and update the tree in the next runloop. This one is triggered in Document::setFocusedElement() if (!focusChangeBlocked && m_focusedElement) { // Create the AXObject cache in a focus change because GTK relies on it. if (AXObjectCache* cache = axObjectCache()) cache->deferFocusedUIElementChangeIfNeeded(oldFocusedElement.get(), newFocusedElement.get()); } Should we just do not defer in this case? Created attachment 345429 [details]
patch
update from review
Zalan, can you take another look at my patch? Comment on attachment 345429 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=345429&action=review > Source/WebCore/ChangeLog:13 > + happens. When the timer fires, you should check if there's a pending layout and let the layout trigger the AX update. This is for the cases when you have different type of mutations coming the same time with the focus change. 1. focus change 2. focus change 3. tree mutation 4. some other style mutation In this case your timer will fire before the layout timer and you should really just not do anything at this point. Created attachment 345583 [details]
patch
update from review.
Comment on attachment 345583 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=345583&action=review > Source/WebCore/accessibility/AXObjectCache.cpp:2861 > + RefPtr<FrameView> frameView = document().view(); > + RenderView* renderView = document().renderView(); > + bool needsLayout = frameView && renderView && (frameView->layoutContext().isLayoutPending() || renderView->needsLayout()); if (!document().view() || document().view()->needsLayout()) return; This should do (when the tree is dirty there must be a pending layout scheduled). Committed r234112: <https://trac.webkit.org/changeset/234112> |