From 30e46e37a3268c5c4ba0730fb7487342961a4c78 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 5 Apr 2023 17:12:07 +0200 Subject: [PATCH] Fix problem with subFocusItem on non-OpenGL QSG The subFocusItem state was forgotten because the old parent was deleted, before its focused child was reparented. The test doesn't pass on Android and makes the test process exit with error. Since it prints warnings that indicate issues further down in the RHI stack, we'll skip it for now on that platform. Task-number: QTBUG-112696 Pick-to: 6.5 6.2 Change-Id: Ibb32a11564ff6fbb2091c241d508f12479b234b0 Reviewed-by: Qt CI Bot Reviewed-by: Volker Hilsheimer --- src/quickwidgets/qquickwidget.cpp | 2 +- .../qquickwidget/tst_qquickwidget.cpp | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 426a9d717f..8a472a4f0a 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -241,7 +241,7 @@ void QQuickWidgetPrivate::handleWindowChange() // must be recreated because its RHI will contain a dangling pointer to // the context. - delete offscreenWindow; + QScopedPointer oldOffScreenWindow(offscreenWindow); // Do not delete before reparenting sgItem offscreenWindow = nullptr; delete renderControl; diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp index 8316625d87..c203366980 100644 --- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp +++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -135,6 +136,7 @@ private slots: #if QT_CONFIG(graphicsview) void focusOnClickInProxyWidget(); #endif + void focusPreserved(); private: QPointingDevice *device = QTest::createTouchDevice(); @@ -939,6 +941,49 @@ void tst_qquickwidget::focusOnClickInProxyWidget() } #endif +void tst_qquickwidget::focusPreserved() +{ + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) + QSKIP("Window Activation is not supported."); + if (QGuiApplication::platformName() == "android") + QSKIP("Test doesn't exit cleanly on Android and generates many warnings - QTBUG-112696"); + + QScopedPointer widget(new QWidget()); + QScopedPointer quick(new QQuickWidget()); + QQuickItem *root = new QQuickItem(); // will be owned by quick after setContent + QScopedPointer content(new QQuickItem()); + content->setActiveFocusOnTab(true); + content->setFocus(true); + quick->setFocusPolicy(Qt::StrongFocus); + quick->setContent(QUrl(), nullptr, root); + root->setFlag(QQuickItem::ItemHasContents); + content->setParentItem(root); + + quick->setGeometry(0, 0, 200, 200); + quick->show(); + quick->setFocus(); + quick->activateWindow(); + QVERIFY(QTest::qWaitForWindowExposed(quick.get())); + QTRY_VERIFY(quick->hasFocus()); + QTRY_VERIFY(content->hasFocus()); + QTRY_VERIFY(content->hasActiveFocus()); + + widget->show(); + widget->setFocus(); + widget->activateWindow(); + QVERIFY(QTest::qWaitForWindowExposed(widget.get())); + QTRY_VERIFY(widget->hasFocus()); + + quick->setParent(widget.get()); + + quick->show(); + quick->setFocus(); + quick->activateWindow(); + QTRY_VERIFY(quick->hasFocus()); + QTRY_VERIFY(content->hasFocus()); + QTRY_VERIFY(content->hasActiveFocus()); +} + QTEST_MAIN(tst_qquickwidget) #include "tst_qquickwidget.moc"