summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-09-24 23:33:27 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-09-28 17:14:20 +0000
commit92d2d31e1a8a03ed56750b5c1c32b5cd22216b99 (patch)
tree45054ec759868391ea4160235ebc079926e42ee5 /tests
parentaf135ac54d7c092210e79997f5a58536056e19a4 (diff)
Don't clear focus if setParent doesn't change the parent
QWidget::setParent might be called to change the window flags, without changing the parent. For those cases, we don't have to clear the focus. Decouple the newParent state from the wasCreated flag. In most places where newParent was tested, wasCreated was either tested previously and can't be false anyway, or the code executed is irrelevant for widgets that are not yet created (there can't be a paint manager). In the remaining case, test wasCreated explicitly to maintain existing logic. Add test for the cases where the previous code broke the focus, both for QWidget and QDialog. Fixes: QTBUG-93005 Change-Id: I39dc179c2d348054de3927aa8b69eecef4935511 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Doris Verria <doris.verria@qt.io> (cherry picked from commit 223066d4319d611e724da69089c8f49d525a2566) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp18
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp72
2 files changed, 90 insertions, 0 deletions
diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
index 1dd053fa3f..03b84c0fda 100644
--- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
+++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
@@ -86,6 +86,7 @@ private slots:
void virtualsOnClose();
void deleteOnDone();
void quitOnDone();
+ void focusWidgetAfterOpen();
};
// Testing get/set functions
@@ -736,5 +737,22 @@ void tst_QDialog::quitOnDone()
QCOMPARE(quitSpy.count(), 1);
}
+void tst_QDialog::focusWidgetAfterOpen()
+{
+ QDialog dialog;
+ dialog.setLayout(new QVBoxLayout);
+
+ QPushButton *pb1 = new QPushButton;
+ QPushButton *pb2 = new QPushButton;
+ dialog.layout()->addWidget(pb1);
+ dialog.layout()->addWidget(pb2);
+
+ pb2->setFocus();
+ QCOMPARE(dialog.focusWidget(), static_cast<QWidget *>(pb2));
+
+ dialog.open();
+ QCOMPARE(dialog.focusWidget(), static_cast<QWidget *>(pb2));
+}
+
QTEST_MAIN(tst_QDialog)
#include "tst_qdialog.moc"
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 54d502c109..e3a553c091 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -430,6 +430,9 @@ private slots:
void deleteWindowInCloseEvent();
void quitOnClose();
+ void setParentChangesFocus_data();
+ void setParentChangesFocus();
+
private:
bool ensureScreenSize(int width, int height);
@@ -12098,5 +12101,74 @@ void tst_QWidget::quitOnClose()
QCOMPARE(quitSpy.count(), 2);
}
+void tst_QWidget::setParentChangesFocus_data()
+{
+ QTest::addColumn<Qt::WindowType>("initialType");
+ QTest::addColumn<bool>("initialParent");
+ QTest::addColumn<Qt::WindowType>("targetType");
+ QTest::addColumn<bool>("targetParent");
+ QTest::addColumn<bool>("reparentBeforeShow");
+ QTest::addColumn<QString>("focusWidget");
+
+ for (const bool before : {true, false}) {
+ const char *tag = before ? "before" : "after";
+ QTest::addRow("give dialog parent, %s", tag)
+ << Qt::Dialog << false << Qt::Dialog << true << before << "lineEdit";
+ QTest::addRow("make dialog parentless, %s", tag)
+ << Qt::Dialog << true << Qt::Dialog << false << before << "lineEdit";
+ QTest::addRow("dialog to sheet, %s", tag)
+ << Qt::Dialog << true << Qt::Sheet << true << before << "lineEdit";
+ QTest::addRow("window to widget, %s", tag)
+ << Qt::Window << true << Qt::Widget << true << before << "windowEdit";
+ QTest::addRow("widget to window, %s", tag)
+ << Qt::Widget << true << Qt::Window << true << before << "lineEdit";
+ }
+}
+
+void tst_QWidget::setParentChangesFocus()
+{
+ QFETCH(Qt::WindowType, initialType);
+ QFETCH(bool, initialParent);
+ QFETCH(Qt::WindowType, targetType);
+ QFETCH(bool, targetParent);
+ QFETCH(bool, reparentBeforeShow);
+ QFETCH(QString, focusWidget);
+
+ QWidget window;
+ window.setObjectName("window");
+ QLineEdit *windowEdit = new QLineEdit(&window);
+ windowEdit->setObjectName("windowEdit");
+ windowEdit->setFocus();
+
+ std::unique_ptr<QWidget> secondary(new QWidget(initialParent ? &window : nullptr, initialType));
+ secondary->setObjectName("secondary");
+ QLineEdit *lineEdit = new QLineEdit(secondary.get());
+ lineEdit->setObjectName("lineEdit");
+ QPushButton *pushButton = new QPushButton(secondary.get());
+ pushButton->setObjectName("pushButton");
+ lineEdit->setFocus();
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+
+ if (reparentBeforeShow) {
+ secondary->setParent(targetParent ? &window : nullptr, targetType);
+ // making a widget into a window doesn't set a focusWidget until shown
+ if (secondary->focusWidget())
+ QCOMPARE(secondary->focusWidget()->objectName(), focusWidget);
+ }
+ secondary->show();
+ QApplication::setActiveWindow(secondary.get());
+ QVERIFY(QTest::qWaitForWindowActive(secondary.get()));
+
+ if (!reparentBeforeShow) {
+ secondary->setParent(targetParent ? &window : nullptr, targetType);
+ secondary->show(); // reparenting hides, so show again
+ QApplication::setActiveWindow(secondary.get());
+ QVERIFY(QTest::qWaitForWindowActive(secondary.get()));
+ }
+ QCOMPARE(QApplication::focusWidget()->objectName(), focusWidget);
+}
+
QTEST_MAIN(tst_QWidget)
#include "tst_qwidget.moc"