diff options
author | Jan Arve Saether <jan-arve.saether@digia.com> | 2014-08-21 10:57:23 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-09-03 16:21:58 +0200 |
commit | a76f0ca34fde78ac64300b8bf9a75b5e1c1b6b51 (patch) | |
tree | 56e8580f13c0927a6606589de30317e3324df113 /src/layouts | |
parent | 9d0c5e5f4f8c233f8424ef2fb2b440b07fe85594 (diff) |
Do not crash when removing children from hidden layouts
The problem was that the proxy items (QQuickGridLayoutItem) that was
added to the layout was not removed when a child item got deleted from
a hidden layout. The proxy item therefore ended up having a dangling
pointer to the deleted item.
The solution is to also update the layout with a new list of items
even when the layout is hidden. This will also fix a problem with that
size hints was not correct when layouts were hidden.
Note that the test included has an expected failure. This is because
the case it tests is not very common and the problem is shared with
positioners. The problem stems from the fact that a layouts implicit
size should change when a child item is changed from implicitly hidden
to explicitly hidden. Unfortuntately, QQuickItem does not notify about
such changes.
This is a problem independent of this crash patch fix, and I would like
to address that in a separate commit.
Change-Id: I67ac28b9d08208432559622c9cd412e24b197b32
Task-number: QTBUG-39045
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
Diffstat (limited to 'src/layouts')
-rw-r--r-- | src/layouts/qquicklinearlayout.cpp | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/src/layouts/qquicklinearlayout.cpp b/src/layouts/qquicklinearlayout.cpp index b3fc8cf3c..d2fb19335 100644 --- a/src/layouts/qquicklinearlayout.cpp +++ b/src/layouts/qquicklinearlayout.cpp @@ -427,7 +427,7 @@ void QQuickGridLayoutBase::invalidate(QQuickItem *childItem) void QQuickGridLayoutBase::updateLayoutItems() { Q_D(QQuickGridLayoutBase); - if (!isReady() || !isVisible()) + if (!isReady()) return; quickLayoutDebug() << "QQuickGridLayoutBase::updateLayoutItems"; d->engine.deleteItems(); @@ -460,7 +460,7 @@ void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &v QObject::connect(item, SIGNAL(implicitHeightChanged()), this, SLOT(invalidateSenderItem())); QObject::connect(item, SIGNAL(baselineOffsetChanged(qreal)), this, SLOT(invalidateSenderItem())); - if (isReady() && isVisible()) + if (isReady()) updateLayoutItems(); } else if (change == ItemChildRemovedChange) { quickLayoutDebug() << "ItemChildRemovedChange"; @@ -470,7 +470,7 @@ void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &v QObject::disconnect(item, SIGNAL(implicitWidthChanged()), this, SLOT(invalidateSenderItem())); QObject::disconnect(item, SIGNAL(implicitHeightChanged()), this, SLOT(invalidateSenderItem())); QObject::disconnect(item, SIGNAL(baselineOffsetChanged(qreal)), this, SLOT(invalidateSenderItem())); - if (isReady() && isVisible()) + if (isReady()) updateLayoutItems(); } @@ -569,7 +569,8 @@ bool QQuickGridLayoutBase::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttac { Q_D(QQuickGridLayoutBase); bool ignoreItem = true; - if (child->isVisible()) { + QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child); + if (childPrivate->explicitVisible) { QQuickGridLayoutItem::effectiveSizeHints_helper(child, sizeHints, &info, true); QSizeF effectiveMaxSize = sizeHints[Qt::MaximumSize]; if (!effectiveMaxSize.isNull()) { |