a11y: Keep current combobox entry in sync

When changing the selected index in a combo box,
also update the current index in the item view's
selection model right away, and don't delay this
until when the combobox popup gets shown in
QComboBox::showPopup.

This is needed to make sure that the selection
is properly exposed to the accessibility layer.

On the accessibility layer, QAccessibleComboBox,
the a11y implementation for the combobox, exposes
the entries in its list child
(s. QAccessibleComboBox::child) and Orca queries
the selected item when the combobox gets focus,
which didn't return the proper results earlier,
resulting in no or the wrong entry getting
announced.

Extend the existing combobox a11y tests
accordingly.

Pick-to: 6.6 6.5
Fixes: QTBUG-117644
Change-Id: Ia26de5eafd229f7686745a2fbe03fc1eb6a713f8
Reviewed-by: Liang Qi <liang.qi@qt.io>
This commit is contained in:
Michael Weghorn 2023-09-26 21:11:18 +02:00
parent 2b63d0ccf3
commit 5093e517b9
2 changed files with 14 additions and 5 deletions

View File

@ -2167,6 +2167,12 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi)
indexBeforeChange = -1;
if (indexChanged || modelResetToEmpty) {
QItemSelectionModel::SelectionFlags selectionMode = QItemSelectionModel::ClearAndSelect;
if (q->view()->selectionBehavior() == QAbstractItemView::SelectRows)
selectionMode.setFlag(QItemSelectionModel::Rows);
if (auto *model = q->view()->selectionModel())
model->setCurrentIndex(currentIndex, selectionMode);
q->update();
emitCurrentIndexChanged(currentIndex);
}
@ -2600,11 +2606,6 @@ void QComboBox::showPopup()
return;
#endif // Q_OS_MAC
// set current item and select it
QItemSelectionModel::SelectionFlags selectionMode = QItemSelectionModel::ClearAndSelect;
if (view()->selectionBehavior() == QAbstractItemView::SelectRows)
selectionMode.setFlag(QItemSelectionModel::Rows);
view()->selectionModel()->setCurrentIndex(d->currentIndex, selectionMode);
QComboBoxPrivateContainer* container = d->viewContainer();
QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt,
QStyle::SC_ComboBoxListBoxPopup, this));

View File

@ -3710,6 +3710,8 @@ void tst_QAccessibility::comboBoxTest()
QCOMPARE(iface->text(QAccessible::Name), QLatin1String("one"));
#endif
QCOMPARE(iface->text(QAccessible::Value), QLatin1String("one"));
QCOMPARE(combo.view()->selectionModel()->currentIndex().row(), 0);
combo.setCurrentIndex(2);
#ifdef Q_OS_UNIX
QCOMPARE(iface->text(QAccessible::Name), QLatin1String("three"));
@ -3720,7 +3722,13 @@ void tst_QAccessibility::comboBoxTest()
QCOMPARE(listIface->role(), QAccessible::List);
QCOMPARE(listIface->childCount(), 3);
QAccessibleSelectionInterface *selectionIface = listIface->selectionInterface();
QVERIFY(selectionIface);
QCOMPARE(selectionIface->selectedItemCount(), 1);
QCOMPARE(listIface->indexOfChild(selectionIface->selectedItem(0)), 2);
QVERIFY(!combo.view()->isVisible());
QCOMPARE(combo.view()->selectionModel()->currentIndex().row(), 2);
QVERIFY(iface->actionInterface());
QCOMPARE(iface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction() << QAccessibleActionInterface::pressAction());
iface->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());