aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickdeferredexecute.cpp
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-12-19 13:38:40 +0100
committerJ-P Nurmi <jpnurmi@qt.io>2017-12-21 14:46:30 +0000
commitc40486acc352d49398186fa32d1ccabdd5fc83c6 (patch)
treeb4f77d072020eef0bb17d4491e98daa1a048537a /src/quicktemplates2/qquickdeferredexecute.cpp
parent1e33020fc02b56001d805d3d66badd41480b746d (diff)
Fix deferred execution
If the QML engine refuses to defer execution of a delegate (it contains an ID), we must make sure to cancel any pending deferred execution for the same delegate. Otherwise, we may end up overriding a custom (non- deferred) delegate with a default (deferred) delegate. This patch adds a new test style "identified" to tst_customization. This style contains delegates with IDs so we can test the behavior with IDs in base styles. Furthermore, overriding delegates is now tested in various ways (with and without IDs in the base and custom styles) in a separate test method. This is done by generating QML code to override delegates with dummy Item instances with appropriate IDs and names. Task-number: QTBUG-65341 Change-Id: Ie6dca287cb74672004d9d8f599760b9d32c3a380 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/quicktemplates2/qquickdeferredexecute.cpp')
-rw-r--r--src/quicktemplates2/qquickdeferredexecute.cpp32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/quicktemplates2/qquickdeferredexecute.cpp b/src/quicktemplates2/qquickdeferredexecute.cpp
index 802ed3d0..ca6953bc 100644
--- a/src/quicktemplates2/qquickdeferredexecute.cpp
+++ b/src/quicktemplates2/qquickdeferredexecute.cpp
@@ -55,13 +55,24 @@ static inline uint qHash(QObject *object, const QString &propertyName)
Q_GLOBAL_STATIC(DeferredStates, deferredStates)
-static void beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &property, QQmlComponentPrivate::DeferredState *deferredState)
+static void cancelDeferred(QObject *object, int propertyIndex)
+{
+ QQmlData *ddata = QQmlData::get(object);
+ auto dit = ddata->deferredData.rbegin();
+ while (dit != ddata->deferredData.rend()) {
+ (*dit)->bindings.remove(propertyIndex);
+ ++dit;
+ }
+}
+
+static bool beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &property, QQmlComponentPrivate::DeferredState *deferredState)
{
QObject *object = property.object();
QQmlData *ddata = QQmlData::get(object);
Q_ASSERT(!ddata->deferredData.isEmpty());
int propertyIndex = property.index();
+ int wasInProgress = enginePriv->inProgressCreations;
for (auto dit = ddata->deferredData.rbegin(); dit != ddata->deferredData.rend(); ++dit) {
QQmlData::DeferredData *deferData = *dit;
@@ -91,12 +102,11 @@ static void beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &pro
// Cleanup any remaining deferred bindings for this property, also in inner contexts,
// to avoid executing them later and overriding the property that was just populated.
- while (dit != ddata->deferredData.rend()) {
- (*dit)->bindings.remove(propertyIndex);
- ++dit;
- }
+ cancelDeferred(object, propertyIndex);
break;
}
+
+ return enginePriv->inProgressCreations > wasInProgress;
}
void beginDeferred(QObject *object, const QString &property)
@@ -106,15 +116,21 @@ void beginDeferred(QObject *object, const QString &property)
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine);
QQmlComponentPrivate::DeferredState *state = new QQmlComponentPrivate::DeferredState;
- beginDeferred(ep, QQmlProperty(object, property), state);
+ if (beginDeferred(ep, QQmlProperty(object, property), state))
+ deferredStates()->insert(qHash(object, property), state);
+ else
+ delete state;
// Release deferred data for those compilation units that no longer have deferred bindings
data->releaseDeferredData();
-
- deferredStates()->insert(qHash(object, property), state);
}
}
+void cancelDeferred(QObject *object, const QString &property)
+{
+ cancelDeferred(object, QQmlProperty(object, property).index());
+}
+
void completeDeferred(QObject *object, const QString &property)
{
QQmlData *data = QQmlData::get(object);