aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickitem.cpp
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2019-10-28 13:41:11 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2019-10-29 07:00:49 +0000
commit73ad6e87bbeceea5830ab3a6b3dc66fa99e30f45 (patch)
tree6eadb286cccad0ccd736a23b3836a27b3e839200 /src/quick/items/qquickitem.cpp
parent76b86342d47df953009457a554245aace49eecf6 (diff)
QQuickItem::setParentItem: add child earlier
Calling (de)refWindow can trigger QQuickItem::windowChanged, which in turn can call a user defined windowChanged handler. If that signal handler were to call setParentItem, we would encounter an inconsistent state: The item already has its parent set, but that parent would lack the item in its children list (as we would only call refWindow at a later point). Fixes: QTBUG-79573 Fixes: QTBUG-73439 Change-Id: I46adaa54a0521b5cd7f37810b3dd1a206e6a09c6 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/quick/items/qquickitem.cpp')
-rw-r--r--src/quick/items/qquickitem.cpp21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 396012e1e6..26f02aeed7 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2748,22 +2748,35 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
}
QQuickWindow *parentWindow = parentItem ? QQuickItemPrivate::get(parentItem)->window : nullptr;
+ bool alreadyAddedChild = false;
if (d->window == parentWindow) {
// Avoid freeing and reallocating resources if the window stays the same.
d->parentItem = parentItem;
} else {
- if (d->window)
- d->derefWindow();
+ auto oldParentItem = d->parentItem;
d->parentItem = parentItem;
+ if (d->parentItem) {
+ QQuickItemPrivate::get(d->parentItem)->addChild(this);
+ alreadyAddedChild = true;
+ }
+ if (d->window) {
+ d->derefWindow();
+ // as we potentially changed d->parentWindow above
+ // the check in derefWindow could not work
+ // thus, we redo it here with the old parent
+ if (!oldParentItem) {
+ QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
+ }
+ }
if (parentWindow)
d->refWindow(parentWindow);
}
d->dirty(QQuickItemPrivate::ParentChanged);
- if (d->parentItem)
+ if (d->parentItem && !alreadyAddedChild)
QQuickItemPrivate::get(d->parentItem)->addChild(this);
- else if (d->window)
+ else if (d->window && !alreadyAddedChild)
QQuickWindowPrivate::get(d->window)->parentlessItems.insert(this);
d->setEffectiveVisibleRecur(d->calcEffectiveVisible());