summaryrefslogtreecommitdiffstats
path: root/src/core/nodes
diff options
context:
space:
mode:
authorSvenn-Arne Dragly <s@dragly.com>2019-02-21 15:54:02 +0100
committerJani Heikkinen <jani.heikkinen@qt.io>2019-02-22 15:00:03 +0000
commite5b256effa320fb7806205f5a37a4dc1943175f0 (patch)
tree0a52d77a881588881bfd03f08414ac8c013c624c /src/core/nodes
parenta48635f21fa68c5033ebe0d6832d405acfcca937 (diff)
Fix broken creation order for nodes used as properties
Otherwise, child nodes may be constructed before their parents and their node creation changes will arrive at the backend out-of-order. This could result in a child node referencing a parent that we have not yet received a creation change for. Also add a unit test to take this case into account. Change-Id: I26b29e63863d1686e7b9239c63297c7e6c341f4e Task-number: QTBUG-73986 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/core/nodes')
-rw-r--r--src/core/nodes/qnode.cpp12
1 files changed, 6 insertions, 6 deletions
diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp
index 83ac49471..8143ccc75 100644
--- a/src/core/nodes/qnode.cpp
+++ b/src/core/nodes/qnode.cpp
@@ -394,15 +394,15 @@ void QNodePrivate::propertyChanged(int propertyIndex)
if (data.canConvert<QNode*>()) {
QNode *node = data.value<QNode*>();
- // Ensure the node has issued a node creation change. We can end
- // up here if a newly created node with a parent is immediately set
+ // Ensure the node and all ancestors have issued their node creation changes.
+ // We can end up here if a newly created node with a parent is immediately set
// as a property on another node. In this case the deferred call to
// _q_postConstructorInit() will not have happened yet as the event
- // loop will still be blocked. So force it here and we catch this
- // eventuality in the _q_postConstructorInit() function so that we
- // do not repeat the creation and new child scene change events.
+ // loop will still be blocked. We need to do this for all ancestors,
+ // since the subtree of this node otherwise can end up on the backend
+ // with a reference to a non-existent parent.
if (node)
- QNodePrivate::get(node)->_q_postConstructorInit();
+ QNodePrivate::get(node)->_q_ensureBackendNodeCreated();
const QNodeId id = node ? node->id() : QNodeId();
return QVariant::fromValue(id);