JUCE Accessibility on `develop`

ok great.
The question here is, can we target 10.9 while still supporting accessibility for people with newer OSX version.
If using feature in newer Xcode version while still using an older SDK would allow this, then this would be great.

I think it would be possible using the @available keyword but as it’s a compiler feature and not part of the SDK we have no way of checking whether it’s available and supported in the user’s build environment.

We are able to use it where we can guarantee that the Xcode version will be >= Xcode 9, for example in the new CoreMidi API which requires on macOS 11, but we can’t make that guarantee here.

I suppose not… I’ll have to defer to the developer that’s struggling with this atm to provide more details.

if __clang_major__ >= 9

See ios - How to know the Objective-C language version in Xcode - Stack Overflow


That might be possible… I’ll look into it as it would be great to be able to support lower deployment targets without disabling accessibility support.

1 Like

Thanks, I’ve added this to develop here:

First of all, I’m really delighted to see this happening.

I’d like to draw attention to the fact that the open source NVDA screen reader is much more widely used on Windows than Narrator, see for example WebAIM: Screen Reader User Survey #8 Results for some evidence. Therefore it would be useful to include NVDA as a screen reader to test with on Windows.

I just checked out the develop branch and started projucer compiled with VS2019. I stumbled upon the following. As a disclaimer, note that I’m blind and therefore can’t verify what stuff looks like visually.

  1. When starting Projucer, in the templates tree view, all nodes are reported as expanded. Pressing left arrow on the nodes seems to collapse them, i.e. when I refocus an item, it’s announced as collapsed. Yet, it looks like no event is fired to point out that the expanded/collapsed state has changed. Pressing right arrow is expected to expand the node if it is expandable, but instead focus moves to the next tree node. Furthermore, It somehow occurs to me that these nodes don’t have any children and therefore the UIA ExpandCollapse pattern’s ExpandCollapseState property should be set to ExpandCollapseState_LeafNode.
  2. When I land on the tree view with tab, the tree view itself seems to be focused, not the active inner node itself.
  3. When I tab from “Open Existing Project…” to the template tree view, NVDA incists on announcing the top window “Projucer window”. I’ve seen this in other plugins as well. This behavior doesn’t occur in Narrator, yet it is slightly annoying. Some quick debugging reveals that NVDA receives a focus event for the foreground window before the tree view itself gets focus.
  4. As already mentioned, it looks like the menu bar is not yet keyboard accessible.

setAccessibilityElement is only available on 10.10+ in modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm

Thank you for the detailed feedback! The data on screen reader usage is very useful. We’ll definitely look into testing with NVDA on Windows and I’ll investigate the issues that you have run into with the Projucer.

1 Like

Thanks, both the PopupMenu and Label issues should now be fixed on develop.

1 Like

The following commit on develop uses the @available keyword when compiling with Clang 9 or above and should allow builds with deployment targets < 10.10 to use the accessibility features:

It also fixes the setAccessibilityElement issue.


I’ve been trying to fit accessibility into my app and it all works fine, apart from sliders. There doesn’t seem to be any way to navigate to a slider without a text box other than with the mouse. And I have lots of these. Is there a way of dealing with this - wantsKeyboardFocus() doesn’t seem to help?.

Can you provide some more information? Are you just using standard juce::Sliders? I’m able to navigate and interact with the sliders in the AccessibilityDemo using both Narrator and VoiceOver without issue.

It seems to me that juce still crashes on 10.9, here is the stacktrace for DemoRunner (crash on startup):

    0   CoreFoundation                      0x00007fff8bb1725c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff902cae75 objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff8b9cf9a6 -[__NSPlaceholderArray initWithObjects:count:] + 358
    3   CoreFoundation                      0x00007fff8ba33440 +[NSArray arrayWithObjects:count:] + 48
    4   DemoRunner                          0x0000000100a665c0 _ZNK4juce20AccessibilityHandler24notifyAccessibilityEventENS_18AccessibilityEventE + 176
    5   DemoRunner                          0x0000000100a60e99 _ZN4juce9Component24internalHierarchyChangedEv + 489
    6   DemoRunner                          0x0000000100a614e6 _ZN4juce9Component12addToDesktopEiPv + 1270
    7   DemoRunner                          0x0000000100b325ee _ZN4juce14TopLevelWindowC2ERKNS_6StringEb + 206
    8   DemoRunner                          0x0000000100a96054 _ZN4juce15ResizableWindowC2ERKNS_6StringENS_6ColourEb + 52
    9   DemoRunner                          0x0000000100aa7805 _ZN4juce14DocumentWindowC2ERKNS_6StringENS_6ColourEib + 85
    10  DemoRunner                          0x00000001002f8660 _ZN21DemoRunnerApplication13MainAppWindowC2ERKN4juce6StringE + 96

I think I see the issue there, can you try with the following patch applied and see if it resolves things?

0001-macOS-Accessibility-Fixed-crashes-on-macOS-10.10-whe.patch (4.1 KB)

It works, thanks !

Great, I’ll get that pushed to develop. Thanks for testing.

So as a user of VoiceOver on the Mac myself, having the accessibility built into the JUCE frameworks will be a game changer. Just looking through the apps that I’ve learned are built on JUCE as a framework, it’s really amazing what could come of this. I’d love to help in any way that I can.
I wouldn’t say that I’m very good with code quite yet (I’m a novice in that area unfortunately), but I’d love to be able to test JUCE implementation in a more practical sense (like how it would work for me to integrate it into the projects I try and create). I realize that this probably has already been asked, but how can I, as a user, help? Are there parts of the branch that I can test on, or would I need to reach out to plug-in manufacturers themselves to sk for testing. Thanks again for making this happen, I CANNOT wait for this to be a reality. Well, I can wait, it’s just I’m beyond excited for when it does.

I was using modified juce::Sliders, and had checked on the Widgets in the Juce Demo. I just went and checked in the accessibility demo. If you look at the rotary sliders and the single horizontal slider without a text box in this demo in VoiceOver, then you can’t navigate to them with Tab and they don’t show up in the list of objects when you hit VO-I. In addition if you use the mouse to select and modify the sliders, VoiceOver still thinks you are on the last button or text field. As far as I can tell there is an assumption that that the object has the keyboard focus, and this is just not happening for a textless slider.

This comes down to the difference between a focusable Component and a keyboard focusable Component which I explained a bit above -

JUCE’s Sliders don’t accept the keyboard focus so tabbing to navigate to them won’t work and they will need to be navigated with the VO keys. The keyboard focus will stay with the last keyboard focused Component until the VO navigation focuses a Component which accepts it.

I’m not seeing this behaviour, if I use VO+I on the AccessibilityDemo I can see all the sliders.