Details
-
Bug
-
Resolution: Fixed
-
Not Evaluated
-
6.11.0 FF
-
None
-
Debian testing, qtbase self-compiled from git dev as of commit 46b2a0c1b6de152fee37bfe0b39e3f2b11ba1b15
-
-
12cd5ef9e (dev), 35ae325fd (6.10), 314270c2c (6.9)
Description
This was originally reported/discussed in the KDE a11y matrix chat (use case: new "View Settings" button in Dolphin's toolbar).
There are (at least) 2 ways to have a QToolButton that can open a menu:
1) by setting a menu directly using QToolButton::setMenu
2) by setting a default action that has a menu using QToolButton::setDefaultAction
From a user perspective, there is no difference regarding what the button looks like and how it is interacted with for the 2 buttons in the following sample program:
#include <QApplication> #include <QHBoxLayout> #include <QMainWindow> #include <QMenu> #include <QToolBar> #include <QToolButton> int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow w; QWidget* widget = new QWidget; w.setCentralWidget(widget); QHBoxLayout* layout = new QHBoxLayout; widget->setLayout(layout); // tool button that has the menu set directly QToolButton* toolButton = new QToolButton; toolButton->setText("button with menu"); QMenu* menu = new QMenu; menu->addAction("first"); menu->addAction("second"); toolButton->setMenu(menu); toolButton->setPopupMode(QToolButton::MenuButtonPopup); layout->addWidget(toolButton); // tool button whose menu comes from the default action QToolButton* toolButton2 = new QToolButton; QMenu* menu2 = new QMenu; menu2->addAction("third"); menu2->addAction("fourth"); QAction* action = new QAction("default action"); action->setMenu(menu2); toolButton2->setDefaultAction(action); layout->addWidget(toolButton2); w.show(); return a.exec(); }
However, on the accessibility layer, they are treated differently, and only the first button (whose menu was set directly using QToolButton::setMenu) indicates that it has a menu by:
- using the Role.PUSH_BUTTON_MENU AT-SPI role
- reporting the StateType.HAS_POPUP AT-SPI state
- exposing the menu as its child
Example querying some of the relevant information using Accerciser (see also attached screenshot that shows it in Accerciser's tree view):
First button:
In [22]: acc.get_name()
Out[22]: 'button with menu'
In [23]: acc.get_role()
Out[23]: <Role.PUSH_BUTTON_MENU: 129>
In [24]: acc.get_state_set().get_states()
Out[24]:
[<StateType.ENABLED: 8>,
<StateType.FOCUSABLE: 11>,
<StateType.SENSITIVE: 24>,
<StateType.SHOWING: 25>,
<StateType.VISIBLE: 30>,
<StateType.HAS_POPUP: 42>]
In [25]: acc.get_child_count()
Out[25]: 1
In [26]: acc.get_child_at_index(0).role
Out[26]: <Role.POPUP_MENU: 41>
Second button:
In [28]: acc.get_name()
Out[28]: 'default action'
In [29]: acc.get_role()
Out[29]: <Role.BUTTON: 43>
In [30]: acc.get_state_set().get_states()
Out[30]:
[<StateType.ENABLED: 8>,
<StateType.FOCUSABLE: 11>,
<StateType.SENSITIVE: 24>,
<StateType.SHOWING: 25>,
<StateType.VISIBLE: 30>]
In [31]: acc.get_child_count()
Out[31]: 0
Expected behavior:
The second button should behave like the first one via its role, HAS_POPUP state and child.