From 04f9219a388ce1f2e2f7d4a1f94e055ce42a22e7 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 13 May 2022 16:40:11 +0200 Subject: QQmlDelegateModel: Consider only top level required properties Required properties deeper inside the delegate must not suppress the passing of model data via the context. Fixes: QTBUG-103479 Change-Id: I2d350d93633a87b90e7a7d08b1e26a06a966b24a Reviewed-by: Fabian Kosmale --- src/qml/qml/qqmlcomponent.cpp | 4 ++-- src/qml/qml/qqmlcomponent_p.h | 2 +- src/qml/qml/qqmlincubator.cpp | 4 ++-- src/qml/qml/qqmlincubator_p.h | 2 +- src/qml/qml/qqmlobjectcreator.cpp | 24 +++++++++++++++--------- src/qml/qml/qqmlobjectcreator_p.h | 8 +++++--- 6 files changed, 26 insertions(+), 18 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 41af4ed67b..26a7b9afbf 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -349,9 +349,9 @@ RequiredProperties &QQmlComponentPrivate::requiredProperties() return state.creator->requiredProperties(); } -bool QQmlComponentPrivate::hadRequiredProperties() const +bool QQmlComponentPrivate::hadTopLevelRequiredProperties() const { - return state.creator->componentHadRequiredProperties(); + return state.creator->componentHadTopLevelRequiredProperties(); } void QQmlComponentPrivate::clear() diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index 26f275f861..55330c6837 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -108,7 +108,7 @@ public: int start; RequiredProperties& requiredProperties(); - bool hadRequiredProperties() const; + bool hadTopLevelRequiredProperties() const; QQmlRefPointer compilationUnit; struct ConstructionState { diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp index 5a3fd2a1f4..52d9fe07ed 100644 --- a/src/qml/qml/qqmlincubator.cpp +++ b/src/qml/qml/qqmlincubator.cpp @@ -696,9 +696,9 @@ RequiredProperties &QQmlIncubatorPrivate::requiredProperties() return creator->requiredProperties(); } -bool QQmlIncubatorPrivate::hadRequiredProperties() const +bool QQmlIncubatorPrivate::hadTopLevelRequiredProperties() const { - return creator->componentHadRequiredProperties(); + return creator->componentHadTopLevelRequiredProperties(); } /*! diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h index b178c6aa29..0d91e63f17 100644 --- a/src/qml/qml/qqmlincubator_p.h +++ b/src/qml/qml/qqmlincubator_p.h @@ -106,7 +106,7 @@ public: void forceCompletion(QQmlInstantiationInterrupt &i); void incubate(QQmlInstantiationInterrupt &i); RequiredProperties &requiredProperties(); - bool hadRequiredProperties() const; + bool hadTopLevelRequiredProperties() const; }; QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index b1bedc7c37..f3af43577d 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -82,6 +82,7 @@ QQmlObjectCreator::QQmlObjectCreator( , propertyCaches(&compilationUnit->propertyCaches) , sharedState(new QQmlObjectCreatorSharedState, QQmlRefPointer::Adopt) , topLevelCreator(true) + , isContextObject(true) , incubator(incubator) { init(std::move(parentContext)); @@ -93,7 +94,7 @@ QQmlObjectCreator::QQmlObjectCreator( sharedState->allJavaScriptObjects = nullptr; sharedState->creationContext = creationContext; sharedState->rootContext.reset(); - sharedState->hadRequiredProperties = false; + sharedState->hadTopLevelRequiredProperties = false; if (auto profiler = QQmlEnginePrivate::get(engine)->profiler) { Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler, @@ -103,15 +104,15 @@ QQmlObjectCreator::QQmlObjectCreator( } } -QQmlObjectCreator::QQmlObjectCreator( - QQmlRefPointer parentContext, +QQmlObjectCreator::QQmlObjectCreator(QQmlRefPointer parentContext, const QQmlRefPointer &compilationUnit, - QQmlObjectCreatorSharedState *inheritedSharedState) + QQmlObjectCreatorSharedState *inheritedSharedState, bool isContextObject) : phase(Startup) , compilationUnit(compilationUnit) , propertyCaches(&compilationUnit->propertyCaches) , sharedState(inheritedSharedState) , topLevelCreator(false) + , isContextObject(isContextObject) , incubator(nullptr) { init(std::move(parentContext)); @@ -1249,7 +1250,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo } if (!type.isInlineComponentType()) { - QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data()); + QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data(), + isContextObject); instance = subCreator.create(); if (!instance) { errors += subCreator.errors; @@ -1258,7 +1260,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo } else { int subObjectId = type.inlineComponentId(); QScopedValueRollback rollback {compilationUnit->icRoot, subObjectId}; - QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data()); + QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data(), + isContextObject); instance = subCreator.create(subObjectId, nullptr, nullptr, CreationFlags::InlineComponent); if (!instance) { errors += subCreator.errors; @@ -1559,7 +1562,8 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * continue; if (postHocIt != postHocRequired.end()) postHocRequired.erase(postHocIt); - sharedState->hadRequiredProperties = true; + if (isContextObject) + sharedState->hadTopLevelRequiredProperties = true; sharedState->requiredProperties.insert(propertyData, RequiredPropertyInfo {compilationUnit->stringAt(property->nameIndex), compilationUnit->finalUrl(), property->location, {}}); @@ -1617,7 +1621,8 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * if (postHocIt != postHocRequired.end()) postHocRequired.erase(postHocIt); - sharedState->hadRequiredProperties = true; + if (isContextObject) + sharedState->hadTopLevelRequiredProperties = true; sharedState->requiredProperties.insert( propertyData, RequiredPropertyInfo { @@ -1647,7 +1652,8 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * continue; postHocRequired.erase(postHocIt); - sharedState->hadRequiredProperties = true; + if (isContextObject) + sharedState->hadTopLevelRequiredProperties = true; sharedState->requiredProperties.insert( propertyData, RequiredPropertyInfo { diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 194a071d95..3e036c0970 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -111,7 +111,7 @@ struct QQmlObjectCreatorSharedState : QQmlRefCount QRecursionNode recursionNode; RequiredProperties requiredProperties; QList allQPropertyBindings; - bool hadRequiredProperties; + bool hadTopLevelRequiredProperties; }; class Q_QML_PRIVATE_EXPORT QQmlObjectCreator @@ -150,7 +150,7 @@ public: QFiniteStack > &allCreatedObjects() { return sharedState->allCreatedObjects; } RequiredProperties &requiredProperties() {return sharedState->requiredProperties;} - bool componentHadRequiredProperties() const {return sharedState->hadRequiredProperties;} + bool componentHadTopLevelRequiredProperties() const {return sharedState->hadTopLevelRequiredProperties;} static QQmlComponent *createComponent(QQmlEngine *engine, QV4::ExecutableCompilationUnit *compilationUnit, @@ -160,7 +160,8 @@ public: private: QQmlObjectCreator(QQmlRefPointer contextData, const QQmlRefPointer &compilationUnit, - QQmlObjectCreatorSharedState *inheritedSharedState); + QQmlObjectCreatorSharedState *inheritedSharedState, + bool isContextObject); void init(QQmlRefPointer parentContext); @@ -218,6 +219,7 @@ private: const QQmlPropertyCacheVector *propertyCaches; QQmlRefPointer sharedState; bool topLevelCreator; + bool isContextObject; QQmlIncubatorPrivate *incubator; QObject *_qobject; -- cgit v1.2.3