aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-12-04 14:06:59 +0100
committerUlf Hermann <ulf.hermann@qt.io>2018-12-12 09:03:56 +0000
commit1d88e9919ff837d535f9bbde53613b6a6b96fcd8 (patch)
tree759b83dcbcff472837c41872b70e7a7ba1ba4c86 /src/qml/qml
parente3446c8225acbaa6a613d6c62e8e2fc58e2b70b0 (diff)
QML: Fix registering and unregistering of context objects
When we add a context object we need to include it into the list of contextObjects of its outer context, so that the outerContext member can be reset when the outer context disappears. On the flip side, we also need to remove it from this list when the object gets removed. We don't need to reset the inner context of an object when the outer context disappears, though. Fixes: QTBUG-72241 Change-Id: Ifd34650d852642a364df23b697d32e3961d0479b Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmlcontext.cpp15
-rw-r--r--src/qml/qml/qqmlcontext_p.h2
-rw-r--r--src/qml/qml/qqmlengine.cpp6
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp12
4 files changed, 22 insertions, 13 deletions
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index cbf5a6e259..eca00ffb51 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -640,7 +640,6 @@ void QQmlContextData::destroy()
QQmlData *co = contextObjects;
contextObjects = contextObjects->nextContextObject;
- co->context = nullptr;
co->outerContext = nullptr;
co->nextContextObject = nullptr;
co->prevContextObject = nullptr;
@@ -783,13 +782,17 @@ void QQmlContextData::refreshExpressions()
}
}
-void QQmlContextData::addObject(QObject *o)
+void QQmlContextData::addObject(QQmlData *data)
{
- QQmlData *data = QQmlData::get(o, true);
-
- Q_ASSERT(data->context == nullptr);
+ if (data->outerContext) {
+ if (data->nextContextObject)
+ data->nextContextObject->prevContextObject = data->prevContextObject;
+ if (data->prevContextObject)
+ *data->prevContextObject = data->nextContextObject;
+ else if (data->outerContext->contextObjects == data)
+ data->outerContext->contextObjects = data->nextContextObject;
+ }
- data->context = this;
data->outerContext = this;
data->nextContextObject = contextObjects;
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index 290b7fc7ee..7e3cef8e1d 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -129,7 +129,7 @@ public:
void setParent(QQmlContextData *, bool stronglyReferencedByParent = false);
void refreshExpressions();
- void addObject(QObject *);
+ void addObject(QQmlData *data);
QUrl resolvedUrl(const QUrl &);
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index c400e9239b..6db43a50eb 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -1518,7 +1518,9 @@ void QQmlEngine::setContextForObject(QObject *object, QQmlContext *context)
}
QQmlContextData *contextData = QQmlContextData::get(context);
- contextData->addObject(object);
+ Q_ASSERT(data->context == nullptr);
+ data->context = contextData;
+ contextData->addObject(data);
}
/*!
@@ -1882,6 +1884,8 @@ void QQmlData::destroyed(QObject *object)
nextContextObject->prevContextObject = prevContextObject;
if (prevContextObject)
*prevContextObject = nextContextObject;
+ else if (outerContext && outerContext->contextObjects == this)
+ outerContext->contextObjects = nextContextObject;
QQmlAbstractBinding *binding = bindings;
while (binding) {
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index c181d791f5..68e2c2c928 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1230,13 +1230,15 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
QQmlContextData *c = ddata->context;
while (c->linkedContext) c = c->linkedContext;
c->linkedContext = context;
- } else
- context->addObject(instance);
+ } else {
+ ddata->context = context;
+ }
ddata->ownContext = ddata->context;
- } else if (!ddata->context)
- context->addObject(instance);
+ } else if (!ddata->context) {
+ ddata->context = context;
+ }
- ddata->outerContext = context;
+ context->addObject(ddata);
if (parserStatus) {
parserStatus->classBegin();