Under MSW, screen readers use the label preceding a control without its
own label, such as wxChoice or wxTextCtrl, as its name, so dialogs are
accessible without doing anything special. Under macOS this didn't
happen, and VoiceOver only read the labels as separate texts, so users
tabbing through a dialog didn't hear what the controls were for.
Now, when a native control without its own label is created right after
a wxStaticText, the label is set as its accessibility title element,
which VoiceOver reads as the name of the control. Notice that for most
controls the accessibility element is the cell and not the view itself,
so this uses NSAccessibilityUnignoredDescendant() to link the elements
actually used by VoiceOver, and uses the document view for the controls
inside a scroll view.
Closes#27060.
The new function allows to set the name used by screen readers for any
window, e.g. for buttons showing only a bitmap or text controls without
a label before them.
Implement it for wxMSW and wxOSX and add documentation and a MSW-only
unit test.
Closes#27056.
The search menu could only be opened by clicking the button showing it,
which doesn't accept focus from the keyboard on purpose, so keyboard and
screen reader users couldn't use it at all.
Handle Alt-Down in the text part of the control and show the menu from
there, as suggested in the comments of the original ticket.
Fixes#18457.
Closes#27093.
The license and credits in the collapsible panes of the generic about
dialog were shown in a wxStaticText, which keyboard and screen reader
users could not Tab to. They are now shown in a read-only multi-line
borderless wxTextCtrl, so they look almost the same but can be focused
and read line by line with the arrow keys, which matters for long
licenses such as the GPL. The control is sized for its text, up to 10
lines under MSW, and scrolls for longer text.
Closes#27055.
VoiceOver users open context menus with VO-Shift-M (where "VO" is the
configured modifier key), which calls accessibilityPerformShowMenu on
the element. wxWidgets didn't handle it, so wxEVT_CONTEXT_MENU was never
generated: nothing happened for most controls, and text controls showed
their native editing menu instead of the one defined by the application.
Now accessibilityPerformShowMenu sends wxEVT_CONTEXT_MENU, with
wxDefaultPosition as for the other keyboard-initiated context menus, and
falls back to the native behaviour if the event is not handled, so text
controls still show their native menu in this case.
Fixes#13010.
Closes#27061.
In wxMSW, single line read-only wxTextCtrl doesn't accept focus from
keyboard, so keyboard and screen reader users can't Tab to it and read
its contents.
Add wxWindow::EnableFocusFromKeyboard(), the counterpart of the existing
DisableFocusFromKeyboard(), to let the application allow this.
Update the documentation and add a wxMSW-only unit test.
Fixes#10760.
Closes#27054.
MSW cross-builds / wxMSW 64 bits not compatible (push) Canceled after 0s
MSW cross-builds / wxMSW/Univ (push) Canceled after 0s
MSW cross-builds / wxMSW 32 bits (push) Canceled after 0s
Code Checks / Check Spelling (push) Canceled after 0s
Code Checks / Check Whitespace (push) Canceled after 0s
Code Checks / Check Mixed EOL (push) Canceled after 0s
Code Checks / Check C++ Style (push) Canceled after 0s
Code Checks / Check All Headers In allheaders.h (push) Canceled after 0s
The generic collapsible header, used by wxCollapsiblePane and so by the
generic about dialog, had two problems for keyboard and screen reader
users under MSW:
- Pressing Enter on the header activated the default button of the
dialog. In wxAboutBox this closed the dialog. Enter now toggles the
header, the same as Space.
- Screen readers could not tell what the header was or if it was open.
It now reports itself as a button with an expanded or collapsed state,
sends a state change event when it toggles, and has a default action.
This also stops screen readers from reading the label twice.
Closes#27048.
When the generic wxInfoBar showed a message, screen readers said
nothing, so their users did not know it had appeared.
The info bar now has the alert accessible role with the message as its
name, and sends an alert event every time ShowMessage() is called. NVDA
reads the message when it is shown, and also when a new message is shown
while the bar is already visible.
Closes#27053.
The generic wxInfoBar was a plain wxControl, not a container, so Tab
gave focus to the info bar window itself and never moved to the close
button or other buttons inside it.
wxInfoBarGeneric now derives from wxNavigationEnabled, the same as
wxGenericCollapsiblePane, so Tab moves to the buttons inside it.
Closes#27052.
Buttons that show only a bitmap have no label, so screen readers only
announce them as "button". This affects, for example, the buttons of
wxEditableListBox and the close button of the generic wxInfoBar.
When a button has no label but has a tooltip, its tooltip is now used as
its accessible name. Buttons with a label are not changed.
Closes#27051.
Strip '&' accelerator markers from the label returned by
wxWindowAccessible::GetName() by using wxControl::GetLabelText() instead
of assigning the raw label directly.
This is an extra bug fix on top of 85c436dcc4 (Fix accessible label of
checkboxes broken by recent changes, 2026-03-06).
See #26184, #26187, #26270.
Closes#26275.
The fix for wxCheckBox accessibility in dark mode in b5ea9cfe86 (Fix
wxCheckBox and wxRadioButton accessibility in wxMSW dark mode,
2026-02-13) broke getting their label in the screen readers as this was
broken by default in wxWindowAccessible::GetName() which has started
being used for them.
Fix this by returning the label and not the (internal) name of the
control from wxWindowAccessible::GetName() by default, instead of only
doing this for wxButton.
See #26184, #26187.
Closes#26270.
Previously these controls acted like generic buttons when they were
owner-drawn which was, in particular, always the case when using dark
mode, because the built-in implementation doesn't do anything useful for
owner-drawn buttons.
Implement IAccessible support for them ourselves in order to make it
work in this case too.
Closes#26184.
Closes#26187.