aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quickwidgets/qquickwidget.cpp18
-rw-r--r--tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp19
2 files changed, 36 insertions, 1 deletions
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index fb3c8554be..5b3e4394ce 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -655,6 +655,9 @@ QQuickWidget::~QQuickWidget()
delete d->root;
d->root = nullptr;
+ if (d->rhi)
+ d->rhi->removeCleanupCallback(this);
+
// NB! resetting graphics resources must be done from this destructor,
// *not* from the private class' destructor. This is due to how destruction
// works and due to the QWidget dtor (for toplevels) destroying the repaint
@@ -1021,8 +1024,19 @@ void QQuickWidgetPrivate::initializeWithRhi()
if (rhi)
return;
- if (QWidgetRepaintManager *repaintManager = tlwd->maybeRepaintManager())
+ if (QWidgetRepaintManager *repaintManager = tlwd->maybeRepaintManager()) {
rhi = repaintManager->rhi();
+ if (rhi) {
+ // We don't own the RHI, so make sure we clean up if it goes away
+ rhi->addCleanupCallback(q, [this](QRhi *rhi) {
+ if (this->rhi == rhi) {
+ invalidateRenderControl();
+ deviceLost = true;
+ this->rhi = nullptr;
+ }
+ });
+ }
+ }
if (!rhi) {
// The widget (and its parent chain, if any) may not be shown at
@@ -1675,6 +1689,8 @@ bool QQuickWidget::event(QEvent *e)
}
case QEvent::WindowAboutToChangeInternal:
+ if (d->rhi)
+ d->rhi->removeCleanupCallback(this);
d->invalidateRenderControl();
d->deviceLost = true;
d->rhi = nullptr;
diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
index fde6945ede..0c88c71582 100644
--- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
+++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
@@ -138,6 +138,7 @@ private slots:
#endif
void focusPreserved();
void accessibilityHandlesViewChange();
+ void cleanupRhi();
private:
QPointingDevice *device = QTest::createTouchDevice();
@@ -1027,6 +1028,24 @@ void tst_qquickwidget::accessibilityHandlesViewChange()
(void)iface->child(0);
}
+class CreateDestroyWidget : public QWidget
+{
+public:
+ using QWidget::create;
+ using QWidget::destroy;
+};
+
+void tst_qquickwidget::cleanupRhi()
+{
+ CreateDestroyWidget topLevel;
+ QQuickWidget quickWidget(&topLevel);
+ quickWidget.setSource(testFileUrl("rectangle.qml"));
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+
+ topLevel.destroy();
+ topLevel.create();
+}
QTEST_MAIN(tst_qquickwidget)