JUCE Accessibility on `develop`

Think of focusContainer and keyboardFocusContainer as two separate concerns - a component can be one of these, none of them, or both, depending on how you want it to behave.

A “focusable” component is one that is enabled and visible (visible also includes components which are obscured by others like the overlay in your first example as this gets complicated when things like AffineTransforms are involved) and a “keyboard focusable” component is a subset of this which has been marked as keyboard focusable with setWantsKeyboardFocus (true);.

The focusContainer flag is used when determining the accessibility element hierarchy that is exposed to a screen reader, so if component A has children B and C and is marked as a focusContainer then the screen reader client sees:

                                          A
                                         | |
                                         B C

where A is the “parent” of B and C in the hierarchy and B and C are siblings. This is used by Narrator and VoiceOver when navigating the UI with the navigation keys.

The keyboardFocusContainer flag is used internally by JUCE to determine which component will receive the keyboard focus when navigating with the tab key or clicking on components. In the above example if A is marked as a keyboardFocusContainer and B and C want the keyboard focus, then clicking on A will “trap” the keyboard focus in the container and tabbing will move between B and C.

We need these two separate focus mechanisms because there needs to be a way of controlling the accessibility hierarchy and focus order that is independent from keyboard focus as you will likely want to expose components to the screen reader client which should not be keyboard focusable, and their parent components shouldn’t interfere with the tab focus by trapping it. However, tabbing and moving keyboard focus should grab the accessibility focus - for example if you are focused on a JUCE window which contains a TextEditor and move keyboard focus to it with the tab key, the screen reader should also move its focus to the editor.

In both of your examples, I think you want to use FocusContainerType::focusContainer and not keyboardFocusContainer as you are trying to control the accessibility navigation.

4 Likes