Ah yes, I see what the issue is. There is a fix for this on develop
here:
Thanks, Iāve pushed a fix for this to develop
here:
If I disable accessibility with setAccessible(false) on a parent component that contains ComboBoxes, the PopupMenus of those combo boxes still appear as accessible.
- would it be possible to add an option for PopupMenus to be created as not accessible?
- would it be possible to use that option to create PopupMenus with accessibility disabled for ComboBoxes that have it disabled?
That seems to work. Thanks
Iām getting some odd behaviour with setting parent components to be non-accessibleā¦
I have a settings panel with a tabbed component within it. Iāve set the tabbed component itself to be non-accessible which leaves the tab buttons, and the content within the tab to remain accessible.
Firstly, this goes against the documentation which says that the child components will also become non-accessible when the parent is set to be non-accessible.
Secondly, when I use Accessibility Inspector and target the area that contains the tabbed component, the inspector highlights the entire window, rather than the next accessible component in the hierarchy (the settings panel in this case) which is what I would have expected. To the inspector, it looks as though thereās large holes in my settings panel.
Maybe this is the expected behaviour and I just need to become more familiar with accessibility clients, but it certainly seems odd to me. The documentation for setAccessible
seems to be wrong either way.
No that doesnāt sound like the desired behaviour. Are you using the latest develop
? Iāve just tried the following example and it seems to be working as expected - Iām able to navigate the window, content and ComboBox
but the entire TabbedComponent
(as well as the buttons and tab content components) are inaccessible:
class MainComponent : public juce::Component
{
public:
//==============================================================================
MainComponent()
{
combo.addItemList ({ "Item 1", "Item 2", "Item 3" }, 1);
combo.setSelectedItemIndex (0);
addAndMakeVisible (combo);
tabComp.addTab ("Tab 1", juce::Colours::transparentBlack, new InnerComp (juce::Colours::hotpink), true);
tabComp.addTab ("Tab 2", juce::Colours::transparentBlack, new InnerComp (juce::Colours::cyan), true);
tabComp.addTab ("Tab 3", juce::Colours::transparentBlack, new InnerComp (juce::Colours::grey), true);
tabComp.addTab ("Tab 4", juce::Colours::transparentBlack, new InnerComp (juce::Colours::yellow), true);
tabComp.addTab ("Tab 5", juce::Colours::transparentBlack, new InnerComp (juce::Colours::orange), true);
addAndMakeVisible (tabComp);
tabComp.setAccessible (false);
setSize (600, 400);
}
~MainComponent() override
{
}
//==============================================================================
void paint (juce::Graphics& g) override
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
}
void resized() override
{
auto bounds = getLocalBounds().reduced (20);
combo.setBounds (bounds.removeFromTop (50).reduced (40, 10));
tabComp.setBounds (bounds);
}
private:
//==============================================================================
// Your private member variables go here...
juce::ComboBox combo;
juce::TabbedComponent tabComp { juce::TabbedButtonBar::Orientation::TabsAtTop };
struct InnerComp : public juce::Component
{
InnerComp (juce::Colour c) : bg (c)
{
label.setJustificationType (juce::Justification::centred);
addAndMakeVisible (label);
addAndMakeVisible (button);
}
void paint (juce::Graphics& g) override
{
g.fillAll (bg);
}
void resized() override
{
auto b = getLocalBounds().reduced (20);
label.setBounds (b.removeFromTop (50));
b.removeFromTop (20);
button.setBounds (b.removeFromTop (35));
}
juce::Colour bg;
juce::Label label { {}, "Hello!" };
juce::TextButton button { "Button" };
};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
Are you able to put together a simple test example which reproduces your issue?
Iām on the latest develop (9db2647971beb24bb5449458090f8c9446fa43bd).
That example doesnāt seem to work as Iād expect either. When I target the blank space to the right of the tab buttons, Accessibility Inspector highlights the window, not the MainComponent:
(Screenshot hides the mouse, but itās to the right of the buttons there).
If I target the space around the tabbed component, the inspector correctly highlights the main component, not the window.
This is on macOS 11.5.2.
Ah gotcha, I think I see whatās happening here. Will push a fix shortly.
Iāve added a fix for this to the develop
branch here:
Awesome, thatās working well now. Thanks!
Having some problems with iOS accessibility on sliders. Nothing I do (changing VoiceOver level of detail, adding names, help, tooltips) to the slider, causes the slider value or slider info to be read out. Iāve also checked it out in the Accessibility inspector and that reports that the slider has neither a label or identifier. On the bright side, the slider value an actually be changed with double-tap and drag. Any thoughts?
Sorry for asking, but I donāt have any experience with VoiceOver or Narrator whatsoever:
are there any good instructions / videos somewhere on how I can actually test this new accessibility feature as a user? I mean: when I start VoiceOver I just get a Window with all kinds of options, but I have not the slightest idea of what I should do to get the tool to read out my plugin components etcā¦
Now that I switched to 6.1.1 Iād like to see how it works on my plugin so I can decide if itās a good idea to announce it in the release notes for the next release
Where I started was with the Apple guide here and particularly the commands section. Itās a good intro, but be sure to read it through so that you can pick up on some of the quirks. Also you should be aware of the settings for levels of detail - these can sometimes influence which text is read. Tabbing through the components gives you a good idea if you need to do something with the default traversal. And also, it helps enormously if you can find a visually impaired beta tester.
Thanks for the pointers!
I was able to do a quick test already on macOS and quickly noticed a few things that donāt work well with my plugin. Mostly traversal order weirdness, no way to change my min/max sliders (which are custom components) although the text edit controls linked to them do work, labels donāt read out (might be a setting), and one button that canāt be accessed by VoiceOver apparently, ā¦
I think itās all probably because of the way Iām doing things in the GUI, so it might require some work to get it to work properly.
If your slider is totally custom them youāre going to have to do the work an write an AccessibilityHandler, but if itās subclassed from juce::Slider it should work. If you have a slider without a text box associated youāll need to call setWantsKeyboardFocus(true).
Thanks for reporting. This has been fixed on the develop
branch here:
I think there is an issue with ListBox
rows that are created with ListBoxModel::refreshComponentForRow
: they seem to be invisible to VoiceOver, and I canāt navigate their child components. An example of such a ListBox
can be found in the Projucer, in extras/Projucer/Source/Project/UI/jucer_FileGroupInformationComponent.h
Iām testing with the latest develop version.
Thereās a fix for this on the develop
branch now:
if I set the visibility false to some components with setVisible (false)
they should be ignored by VoiceOver or Narrator. Am I wrong? For example for Standalone apps Iāve removed the default menu of Audio Device Manager but with the voiceOver I can open it anyway