summaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlpropertycache.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2016-05-02 16:55:36 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-09-30 08:17:39 +0000
commitc9ffed92a0dee0ae00a9632177ea42f85ea8a48c (patch)
treecf56b80e4d9771193ca179f58108ecb2a94671fb /src/qml/qml/qqmlpropertycache.cpp
parent79cfc8788d6267eeb263983466ba21758f618dcd (diff)
Fix crash with window-less QQuickItems
Mark QQuickItem visual children directly in QQuickItem instead of relying on the item being a (grand) child of a window. [ChangeLog][QtQuick] Fix crash with QQuickItems created via JavaScript being garbage collected sometimes when they're not assigned to a window. This may happen even in qmlscene when between the creation of the root item and the assignment to the QQuickWindow the garbage collector runs. The previous approach of a persistent in QQuickView marking the visual item hierarchy relies on the existence of a view. The only thing left to do in the view and qml window implementation is enforcing the CppOwnership policy set on the content item in QQuickWindow by ensuring the presence of the JS wrapper, replacing the persistent with a weak value. This also introduces a new internal mechanism for QObject sub-classes to provide their own V4 JS wrapper types. Task-number: QTBUG-39888 Change-Id: Icd45a636a6d4e4528fc19165b13f4e1ca7967087 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlpropertycache.cpp')
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index e8c9989fdf..be730c7ac9 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -234,7 +234,7 @@ Creates a new empty QQmlPropertyCache.
QQmlPropertyCache::QQmlPropertyCache(QV4::ExecutionEngine *e)
: engine(e), _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
signalHandlerIndexCacheStart(0), _hasPropertyOverrides(false), _ownMetaObject(false),
- _metaObject(0), argumentsCache(0)
+ _metaObject(0), argumentsCache(0), _jsFactoryMethodIndex(-1)
{
Q_ASSERT(engine);
}
@@ -245,7 +245,7 @@ Creates a new QQmlPropertyCache of \a metaObject.
QQmlPropertyCache::QQmlPropertyCache(QV4::ExecutionEngine *e, const QMetaObject *metaObject)
: engine(e), _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
signalHandlerIndexCacheStart(0), _hasPropertyOverrides(false), _ownMetaObject(false),
- _metaObject(0), argumentsCache(0)
+ _metaObject(0), argumentsCache(0), _jsFactoryMethodIndex(-1)
{
Q_ASSERT(engine);
Q_ASSERT(metaObject);
@@ -518,10 +518,16 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
for (int ii = 0; ii < classInfoCount; ++ii) {
int idx = ii + classInfoOffset;
- if (0 == qstrcmp(metaObject->classInfo(idx).name(), "qt_HasQmlAccessors")) {
+ const char * const classInfoName = metaObject->classInfo(idx).name();
+ if (0 == qstrcmp(classInfoName, "qt_HasQmlAccessors")) {
hasFastProperty = true;
- } else if (0 == qstrcmp(metaObject->classInfo(idx).name(), "DefaultProperty")) {
+ } else if (0 == qstrcmp(classInfoName, "DefaultProperty")) {
_defaultPropertyName = QString::fromUtf8(metaObject->classInfo(idx).value());
+ } else if (0 == qstrcmp(classInfoName, "qt_QmlJSWrapperFactoryMethod")) {
+ const char * const factoryMethod = metaObject->classInfo(idx).value();
+ _jsFactoryMethodIndex = metaObject->indexOfSlot(factoryMethod);
+ if (_jsFactoryMethodIndex != -1)
+ _jsFactoryMethodIndex -= metaObject->methodOffset();
}
}