diff options
author | Axel Spoerl <axel.spoerl@qt.io> | 2023-06-24 11:52:18 +0200 |
---|---|---|
committer | Axel Spoerl <axel.spoerl@qt.io> | 2023-07-06 08:41:04 +0200 |
commit | bbb71e7e80f292c2e69faef81b1624832981147e (patch) | |
tree | c8f1a60defc2725399dc94f4e205120cea006a96 /tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp | |
parent | ef9fe7a99a9a6779e7133167fe84426bfe9cc371 (diff) |
QDialogButtonBox - Update focus chain when buttons show or hide
Hiding a button in a QDialogButtonBox doesn't remove its default and
focus behavior. Hiding the button shown in the first position, breaks
the focus chain. Tabbing between the button is no longer possible.
This patch implements listening to the buttons' HideToParent and
ShowToParent events. Hidden buttons are removed from the button box
and kept in a separate hash. That ensures focus chain consistency.
When they are shown again, they are added to the button logic and
their default/focus behavior is restored.
An autotest is added in tst_QDialogButtonBox.
Fixes: QTBUG-114377
Pick-to: 6.6 6.5
Change-Id: Id10c4675f43d6007206e41c694688c4f0a34ee52
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp')
-rw-r--r-- | tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp index df26b4c5da..c3f8fb0e30 100644 --- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp @@ -8,6 +8,8 @@ #include <QtWidgets/QDialog> #include <QtGui/QAction> #include <qdialogbuttonbox.h> +#include <QtWidgets/private/qdialogbuttonbox_p.h> +#include <QtWidgets/private/qabstractbutton_p.h> #include <limits.h> Q_DECLARE_METATYPE(QDialogButtonBox::ButtonRole) @@ -49,6 +51,9 @@ private slots: void clear(); void removeButton_data(); void removeButton(); +#ifdef QT_BUILD_INTERNAL + void hideAndShowButton(); +#endif void buttonRole_data(); void buttonRole(); void setStandardButtons_data(); @@ -372,6 +377,51 @@ void tst_QDialogButtonBox::removeButton() delete button; } +#ifdef QT_BUILD_INTERNAL +void tst_QDialogButtonBox::hideAndShowButton() +{ + QDialogButtonBox buttonBox; + QDialogButtonBoxPrivate *d = static_cast<QDialogButtonBoxPrivate *>(QObjectPrivate::get(&buttonBox)); + auto *apply = buttonBox.addButton( "Apply", QDialogButtonBox::ApplyRole ); + auto *accept = buttonBox.addButton( "Accept", QDialogButtonBox::AcceptRole ); + buttonBox.addButton( "Reject", QDialogButtonBox::RejectRole ); + auto *widget = new QWidget(); + auto *layout = new QHBoxLayout(widget); + layout->addWidget(&buttonBox); + + // apply button shows first on macOS. accept button on all other OSes. + QAbstractButton *hideButton; +#ifdef Q_OS_MACOS + hideButton = apply; + Q_UNUSED(accept); +#else + hideButton = accept; + Q_UNUSED(apply); +#endif + + hideButton->hide(); + widget->show(); + QVERIFY(QTest::qWaitForWindowExposed(widget)); + QVERIFY(buttonBox.focusWidget()); // QTBUG-114377: Without fixing, focusWidget() == nullptr + QCOMPARE(d->visibleButtons().count(), 2); + QCOMPARE(d->hiddenButtons.count(), 1); + QVERIFY(d->hiddenButtons.contains(hideButton)); + QCOMPARE(buttonBox.buttons().count(), 3); + QSignalSpy spy(qApp, &QApplication::focusChanged); + QTest::sendKeyEvent(QTest::KeyAction::Click, &buttonBox, Qt::Key_Tab, QString(), Qt::KeyboardModifiers()); + QCOMPARE(spy.count(), 1); // QTBUG-114377: Without fixing, tabbing wouldn't work. + hideButton->show(); + QCOMPARE_GE(spy.count(), 1); + QTRY_COMPARE(QApplication::focusWidget(), hideButton); + QCOMPARE(d->visibleButtons().count(), 3); + QCOMPARE(d->hiddenButtons.count(), 0); + QCOMPARE(buttonBox.buttons().count(), 3); + spy.clear(); + QTest::sendKeyEvent(QTest::KeyAction::Click, &buttonBox, Qt::Key_Backtab, QString(), Qt::KeyboardModifiers()); + QCOMPARE(spy.count(), 1); +} +#endif + void tst_QDialogButtonBox::testDelete() { QDialogButtonBox buttonBox; |