diff options
-rw-r--r-- | src/quickwidgets/qquickwidget.cpp | 25 | ||||
-rw-r--r-- | tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp | 23 |
2 files changed, 48 insertions, 0 deletions
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 4a98122fea..9dba007540 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -154,7 +154,18 @@ void QQuickWidgetPrivate::invalidateRenderControl() void QQuickWidgetPrivate::handleWindowChange() { + if (offscreenWindow->isPersistentSceneGraph() && qGuiApp->testAttribute(Qt::AA_ShareOpenGLContexts)) + return; + + // In case of !isPersistentSceneGraph or when we need a new context due to + // the need to share resources with the new window's context, we must both + // invalidate the scenegraph and destroy the context. With + // QQuickRenderControl destroying the context must be preceded by an + // invalidate to prevent being left with dangling context references in the + // rendercontrol. + invalidateRenderControl(); + if (!useSoftwareRenderer) destroyContext(); } @@ -417,6 +428,20 @@ QObject *QQuickWidgetPrivate::focusObject() persistent. The OpenGL context is thus not destroyed when hiding the widget. The context is destroyed only when the widget is destroyed or when the widget gets reparented into another top-level widget's child hierarchy. + However, some applications, in particular those that have their own + graphics resources due to performing custom OpenGL rendering in the Qt + Quick scene, may wish to disable the latter since they may not be prepared + to handle the loss of the context when moving a QQuickWidget into another + window. Such applications can set the + QCoreApplication::AA_ShareOpenGLContexts attribute. For a discussion on the + details of resource initialization and cleanup, refer to the QOpenGLWidget + documentation. + + \note QQuickWidget offers less fine-grained control over its internal + OpenGL context than QOpenGLWidget, and there are subtle differences, most + notably that disabling the persistent scene graph will lead to destroying + the context on a window change regardless of the presence of + QCoreApplication::AA_ShareOpenGLContexts. \section1 Limitations diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp index 09359060f6..7676bd6c31 100644 --- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp +++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp @@ -34,6 +34,7 @@ #include <QtQuick/qquickitem.h> #include "../../shared/util.h" #include <QtGui/QWindow> +#include <QtGui/QImage> #include <QtCore/QDebug> #include <QtQml/qqmlengine.h> @@ -55,6 +56,7 @@ private slots: void readback(); void renderingSignals(); void grabBeforeShow(); + void reparentToNewWindow(); }; @@ -301,6 +303,27 @@ void tst_qquickwidget::grabBeforeShow() QVERIFY(!widget.grab().isNull()); } +void tst_qquickwidget::reparentToNewWindow() +{ + QWidget window1; + QWidget window2; + + QQuickWidget *qqw = new QQuickWidget(&window1); + qqw->setSource(testFileUrl("rectangle.qml")); + window1.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window1, 5000)); + window2.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window2, 5000)); + + QSignalSpy afterRenderingSpy(qqw->quickWindow(), &QQuickWindow::afterRendering); + qqw->setParent(&window2); + qqw->show(); + QTRY_VERIFY(afterRenderingSpy.size() > 0); + + QImage img = qqw->grabFramebuffer(); + QCOMPARE(img.pixel(5, 5), qRgb(255, 0, 0)); +} + QTEST_MAIN(tst_qquickwidget) #include "tst_qquickwidget.moc" |