aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-01-03 10:38:33 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-06 10:40:08 +0100
commit39540124dd0900e0c99dcda8c0ebdf4f3cea8d5e (patch)
tree8fb7174b6523945101f7bd5177b973a745b357de /src/quick
parente3232bce40ddefd3b4dfa57a923b15cb47f051bf (diff)
Fix interaction of QQuickItems with the garbage collector
The QObject ownership of QQuickItem objects is not accessible / mutable in QML, because the parent property maps to the (dynamic) visual parent. There are use-cases of creating QQuickItem objects without a QObject parent and to support this, the visual parent needs to mark its visual children in order to provide intuitive semantics. [ChangeLog][QtQuick][Import Behavior Changes] A QQuick Item is now strongly referenced by its visual parent item, so it doesn't require a QObject parent to stay alive. Task-number: QTBUG-35913 Change-Id: Ief2d40ac76298a0cf241ca73ff654c4ecfa12748 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/qquickitem.cpp11
-rw-r--r--src/quick/items/qquickitem_p.h3
-rw-r--r--src/quick/items/qquickview.cpp27
-rw-r--r--src/quick/items/qquickview_p.h22
4 files changed, 63 insertions, 0 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 8c94b9dd5b..72b0e588ec 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -6478,6 +6478,17 @@ void QQuickItemPrivate::incrementCursorCount(int delta)
#endif
}
+void QQuickItemPrivate::markObjects(QV4::ExecutionEngine *e)
+{
+ Q_Q(QQuickItem);
+ QQmlData *ddata = QQmlData::get(q);
+ if (ddata)
+ ddata->jsWrapper.markOnce(e);
+
+ foreach (QQuickItem *child, childItems)
+ QQuickItemPrivate::get(child)->markObjects(e);
+}
+
#ifndef QT_NO_CURSOR
/*!
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index ef5c63e40f..96cb9e8843 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -583,6 +583,9 @@ public:
virtual void mirrorChange() {}
void incrementCursorCount(int delta);
+
+ // recursive helper to let a visual parent mark its visual children
+ void markObjects(QV4::ExecutionEngine *e);
};
/*
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index d1fe489dcb..61f0f9bec2 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -56,6 +56,26 @@
QT_BEGIN_NAMESPACE
+DEFINE_MANAGED_VTABLE(QQuickRootItemMarker);
+
+QQuickRootItemMarker::QQuickRootItemMarker(QQuickViewPrivate *view)
+ : QV4::Object(QQmlEnginePrivate::getV4Engine(view->engine.data()))
+ , view(view)
+{
+ setVTable(&static_vtbl);
+}
+
+void QQuickRootItemMarker::markObjects(QV4::Managed *that, QV4::ExecutionEngine *e)
+{
+ QQuickItem *root = static_cast<QQuickRootItemMarker*>(that)->view->root;
+ if (root) {
+ QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(root);
+ rootPrivate->markObjects(e);
+ }
+
+ QV4::Object::markObjects(that, e);
+}
+
void QQuickViewPrivate::init(QQmlEngine* e)
{
Q_Q(QQuickView);
@@ -68,6 +88,13 @@ void QQuickViewPrivate::init(QQmlEngine* e)
if (!engine.data()->incubationController())
engine.data()->setIncubationController(q->incubationController());
+ {
+ QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine.data());
+ QV4::Scope scope(v4);
+ QV4::Scoped<QQuickRootItemMarker> v(scope, new (v4->memoryManager) QQuickRootItemMarker(this));
+ rootItemMarker = v;
+ }
+
if (QQmlDebugService::isDebuggingEnabled())
QQmlInspectorService::instance()->addView(q);
}
diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h
index 170c93a6cf..e18b45dfbe 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -51,12 +51,17 @@
#include <QtCore/QWeakPointer>
#include <QtQml/qqmlengine.h>
+#include <private/qv4object_p.h>
#include "qquickwindow_p.h"
#include "qquickitemchangelistener_p.h"
QT_BEGIN_NAMESPACE
+namespace QV4 {
+struct ExecutionEngine;
+}
+
class QQmlContext;
class QQmlError;
class QQuickItem;
@@ -94,6 +99,23 @@ public:
QQuickView::ResizeMode resizeMode;
QSize initialSize;
QElapsedTimer frameTimer;
+ QV4::PersistentValue rootItemMarker;
+};
+
+struct QQuickRootItemMarker : public QV4::Object
+{
+ Q_MANAGED
+
+ QQuickRootItemMarker(QQuickViewPrivate *view);
+
+ static void destroy(Managed *that)
+ {
+ static_cast<QQuickRootItemMarker*>(that)->~QQuickRootItemMarker();
+ }
+
+ static void markObjects(Managed *that, QV4::ExecutionEngine *e);
+
+ QQuickViewPrivate *view;
};
QT_END_NAMESPACE