summaryrefslogtreecommitdiffstats
path: root/src/layouts
diff options
context:
space:
mode:
authorJan Arve Saether <jan-arve.saether@digia.com>2014-08-21 10:57:23 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-09-03 16:21:58 +0200
commita76f0ca34fde78ac64300b8bf9a75b5e1c1b6b51 (patch)
tree56e8580f13c0927a6606589de30317e3324df113 /src/layouts
parent9d0c5e5f4f8c233f8424ef2fb2b440b07fe85594 (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.cpp9
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()) {