I have my mod matrix in a view port. There are 18 rows. I navigate there with screen reader, it will only show me 13 rows. I scroll up, now I can access all 18. It seems any component that is outside the window bounds doesn’t work with screen reader.
Is there a way to auto scroll the viewport? Otherwise there is no way a blind user will know to scroll the viewport or how hard to scroll it.
With the current API, I don’t see any way to do this. I think AccessibilityHandler::grabFocusInternal needs to walk up the component hierarchy and find an viewports and scroll the component into view. I’m not sure how this would work with custom scrolling components that aren’t viewports.
Components that are not within the visible area of the viewport can still gain keyboard focus using Tab, but the VoiceOver cursor doesn’t follow them. Using VO+arrow keys to navigate only lets you access things that are visible in the viewport.
It’s also possible to access the scrollbars using a screenreader which seems odd to me - a screenreader user shouldn’t really need to be aware that they’re in a viewport as it’s a purely visual concept IMO.
In general it seems that it would make sense for a Viewport to check if the component with keyboard focus is within its hierarchy and if so automatically scroll to make that component centred. I assume that would then allow screenreaders to follow focus when using Tab, but don’t think it would solve the “normal” VO+arrow keys traversal.
One of our Qt coworkers shared this gif showing how the equivalent works in Qt if it’s of any use:
Esentially the ScrollArea knows if the next thing to be tabbed-to is not entirely on-screen and so scrolls along to make sure it’s fully visible before passing on the keyboard focus.
Not sure how it works for horizontal + vertical scrolling but I’d imagine very similar behaviour.
I have found a workaround to make the Viewport more accessible. The main idea is to make sure that the child components are visible by the accessibility client, even when they are not visible on screen.
For that I used a custom AccessibilityHandler whose only purpose is to raise the AccessibleState:: Flags::accessibleOffscreen flag: