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 AffineTransform
s 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.