diff options
author | Charles Yin <charles.yin@nokia.com> | 2012-04-17 16:47:33 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-17 13:36:22 +0200 |
commit | f92c3aecd08eef468f9a47f2e970f22beecc8216 (patch) | |
tree | ac87f59b2c2564669b437f3b5cd035cb1c7fda86 | |
parent | 812997036a44733c3407d925f42d98c4ff0e6c6f (diff) |
Set rootItem'ownership as CppOwnerShip
rootItem should not be deleted until the QQuickCanvas itself has been deleted.
Set the rootItem's object ownership to CppOwnerShip can prevent it being destroyed
by javascript destroy() method or v8 garbage collection.
Change-Id: I7d83fec8ffcb8062d143b1b050a38368a2af800f
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Reviewed-by: J-P Nurmi <j-p.nurmi@nokia.com>
-rw-r--r-- | src/quick/items/qquickcanvas.cpp | 1 | ||||
-rw-r--r-- | tests/auto/quick/qquickcanvas/data/ownershipRootItem.qml | 11 | ||||
-rw-r--r-- | tests/auto/quick/qquickcanvas/qquickcanvas.pro | 3 | ||||
-rw-r--r-- | tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp | 54 |
4 files changed, 67 insertions, 2 deletions
diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp index 382c5e8d45..0748dad8ed 100644 --- a/src/quick/items/qquickcanvas.cpp +++ b/src/quick/items/qquickcanvas.cpp @@ -330,6 +330,7 @@ void QQuickCanvasPrivate::init(QQuickCanvas *c) Q_Q(QQuickCanvas); rootItem = new QQuickRootItem; + QQmlEngine::setObjectOwnership(rootItem, QQmlEngine::CppOwnership); QQuickItemPrivate *rootItemPrivate = QQuickItemPrivate::get(rootItem); rootItemPrivate->canvas = q; rootItemPrivate->canvasRefCount = 1; diff --git a/tests/auto/quick/qquickcanvas/data/ownershipRootItem.qml b/tests/auto/quick/qquickcanvas/data/ownershipRootItem.qml new file mode 100644 index 0000000000..dfc4159f4e --- /dev/null +++ b/tests/auto/quick/qquickcanvas/data/ownershipRootItem.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +import QtQuick.Window 2.0 as Window + +Window.Window { +RootItemAccessor { + id:accessor + objectName:"accessor" + Component.onCompleted:accessor.rootItem(); +} + +}
\ No newline at end of file diff --git a/tests/auto/quick/qquickcanvas/qquickcanvas.pro b/tests/auto/quick/qquickcanvas/qquickcanvas.pro index 817eb2534f..b9ed73d577 100644 --- a/tests/auto/quick/qquickcanvas/qquickcanvas.pro +++ b/tests/auto/quick/qquickcanvas/qquickcanvas.pro @@ -7,7 +7,7 @@ include (../../shared/util.pri) macx:CONFIG -= app_bundle CONFIG += parallel_test -QT += core-private gui-private qml-private quick-private testlib +QT += core-private gui-private qml-private quick-private v8-private testlib TESTDATA = data/* @@ -15,4 +15,3 @@ OTHER_FILES += \ data/AnimationsWhileHidden.qml \ data/Headless.qml - diff --git a/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp b/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp index 9b33fb1d6f..402e81e640 100644 --- a/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp +++ b/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp @@ -50,6 +50,7 @@ #include <QtGui/QWindowSystemInterface> #include "../../shared/util.h" #include <QSignalSpy> +#include <private/qquickcanvas_p.h> struct TouchEventData { QEvent::Type type; @@ -108,6 +109,36 @@ static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPoin } \ } + +class RootItemAccessor : public QQuickItem +{ + Q_OBJECT +public: + RootItemAccessor() + : m_rootItemDestroyed(false) + , m_rootItem(0) + { + } + Q_INVOKABLE QQuickItem *rootItem() + { + if (!m_rootItem) { + QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas()); + m_rootItem = c->rootItem; + QObject::connect(m_rootItem, SIGNAL(destroyed()), this, SLOT(rootItemDestroyed())); + } + return m_rootItem; + } + bool isRootItemDestroyed() {return m_rootItemDestroyed;} +public slots: + void rootItemDestroyed() { + m_rootItemDestroyed = true; + } + +private: + bool m_rootItemDestroyed; + QQuickItem *m_rootItem; +}; + class TestTouchItem : public QQuickRectangle { Q_OBJECT @@ -214,6 +245,7 @@ private slots: void ignoreUnhandledMouseEvents(); + void ownershipRootItem(); private: QTouchDevice *touchDevice; }; @@ -770,6 +802,28 @@ void tst_qquickcanvas::ignoreUnhandledMouseEvents() delete canvas; } + +void tst_qquickcanvas::ownershipRootItem() +{ + qmlRegisterType<RootItemAccessor>("QtQuick", 2, 0, "RootItemAccessor"); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("ownershipRootItem.qml")); + QObject* created = component.create(); + + QQuickCanvas* canvas = qobject_cast<QQuickCanvas*>(created); + QVERIFY(canvas); + QTest::qWaitForWindowShown(canvas); + + RootItemAccessor* accessor = canvas->findChild<RootItemAccessor*>("accessor"); + QVERIFY(accessor); + engine.collectGarbage(); + + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::processEvents(); + QVERIFY(!accessor->isRootItemDestroyed()); +} QTEST_MAIN(tst_qquickcanvas) #include "tst_qquickcanvas.moc" |