[iOS] Tighten up VoiceOver hiding logic in the tab grid.
The tab grid contains a scroll view holding three view controllers (the incognito tabs, the regular tabs, and the recent tabs). By default, all of the contents of a scroll view can be read and navigated via VoiceOver. For the tab grid, only the view controller which is currently visible (the "current page view controller") should be exposed to VoiceOver. The logic to manage this is (prior to this CL) mostly in TabGridViewController's -setCurrentPage:animated: method. If one of the view controllers that's not visible in the scroll view has its contents focused with VoiceOver, the scroll view will show the focused content without triggering any of the other scrolling behavior. In the tab grid, this means that the page control will go out of sync with the page being displayed (which may lead to consistency DCHECKs or other problems). There were at least two bugs in this code. First, the first time the tab grid is entered, if the user navigates to the right (in LTR) in VoiceOver, they will focus the first line of text in the Recent Tabs view controller. As far as I can tell, this bug hasn't been reported. Second (crbug.com/980844), if a user is in the tab grid when they close the last incognito tab, they will switch to the regular tabs page, but the in- cognito tabs page will have its text focused and visible. Both bugs arise from the accessibilityElementsHidden property of the non- current view controller not being set to NO at the correct time. For the first bug, this is a matter of setting all non-current view con- trollers to be invisible as part of -viewDidLoad. For the second bug, the general pattern was to set the value of _currentPage and then set self.currentPageViewController.view.accessibilityElementsHidden to NO. However, when the scroll view is scrolled with animation, _currentPage is only set when the animation ends, and -setCurrentPage:animated was marking the current view as non-hidden immediately, not when the animation completed. This means that (in the case of this bug) the incognito view controller was re-marked as not-hidden, and the regular tabs view controller remained hidden. The fix in this CL is to replace direct writes to _currentPage with a property setter that always marks the prior page view controller as hidden-to-VoiceOver and always marks the new current page as unhidden. Since this setter used to induce scrolling (which itself needed to update the current page), scrolling has been pulled into an explicit -scrollToPage:animated: method. The currentPage property no longer scrolls implicitly, and is now usually set as a part of scrolling. Bug: 980844 Change-Id: I7ccb904442a55d791df95ab4c0c8c2795a6c74e8 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1813332 Commit-Queue: Mark Cogan <marq@chromium.org> Reviewed-by:Robbie Gibson <rkgibson@google.com> Reviewed-by:
edchin <edchin@chromium.org> Cr-Commit-Position: refs/heads/master@{#699707}
Showing
Please register or sign in to comment