summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
diff options
context:
space:
mode:
authorAxel Spoerl <axel.spoerl@qt.io>2023-06-24 11:52:18 +0200
committerAxel Spoerl <axel.spoerl@qt.io>2023-07-06 08:41:04 +0200
commitbbb71e7e80f292c2e69faef81b1624832981147e (patch)
treec8f1a60defc2725399dc94f4e205120cea006a96 /tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
parentef9fe7a99a9a6779e7133167fe84426bfe9cc371 (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.cpp50
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;