aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/quicklayouts/qquicklayout.cpp20
-rw-r--r--src/quicktemplates/qquickapplicationwindow.cpp21
2 files changed, 32 insertions, 9 deletions
diff --git a/src/quicklayouts/qquicklayout.cpp b/src/quicklayouts/qquicklayout.cpp
index 3da13ba10a..0dd0d27eed 100644
--- a/src/quicklayouts/qquicklayout.cpp
+++ b/src/quicklayouts/qquicklayout.cpp
@@ -948,12 +948,30 @@ void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value)
void QQuickLayout::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickLayout);
+ qCDebug(lcQuickLayouts) << "QQuickLayout::geometryChange"
+ << oldGeometry << "-->" << newGeometry;
+
QQuickItem::geometryChange(newGeometry, oldGeometry);
+
if ((invalidated() && !qobject_cast<QQuickLayout *>(parentItem())) ||
d->m_disableRearrange || !isReady())
return;
- qCDebug(lcQuickLayouts) << "QQuickLayout::geometryChange" << newGeometry << oldGeometry;
+ // The geometryChange call above might recursively update the
+ // geometry of this layout, via item change listeners, in which
+ // case the recursive call has already rearranged the layout for
+ // the new size. We don't want to rearrange here based on the old
+ // 'new geometry', as that would revert the most up to date layout.
+ const qreal w = d->width.valueBypassingBindings();
+ const qreal h = d->height.valueBypassingBindings();
+ const QSizeF currentSize(w, h);
+ if (currentSize != newGeometry.size()) {
+ qCDebug(lcQuickLayouts) << "QQuickItem::geometryChange resulted"
+ << "in size change from" << newGeometry.size() << "to"
+ << currentSize << "; layout should already be up to date.";
+ return;
+ }
+
rearrange(newGeometry.size());
}
diff --git a/src/quicktemplates/qquickapplicationwindow.cpp b/src/quicktemplates/qquickapplicationwindow.cpp
index 489dd48f47..871ae593ed 100644
--- a/src/quicktemplates/qquickapplicationwindow.cpp
+++ b/src/quicktemplates/qquickapplicationwindow.cpp
@@ -139,20 +139,25 @@ void QQuickApplicationWindowPrivate::updateHasBackgroundFlags()
void QQuickApplicationWindowPrivate::relayout()
{
Q_Q(QQuickApplicationWindow);
- if (!componentComplete || insideRelayout)
+ if (!componentComplete)
return;
+ // Note: We track whether we are inside relayout, but we do
+ // allow nested relayouts, as those are necessary to compute
+ // the height and position of footers when using safe areas.
QScopedValueRollback<bool> guard(insideRelayout, true);
- qreal menuBarHeight = menuBar && menuBar->isVisible() ? menuBar->height() : 0;
- qreal headerheight = header && header->isVisible() ? header->height() : 0;
- qreal footerHeight = footer && footer->isVisible() ? footer->height() : 0;
+ // Re-evaluate component heights for each use, as they
+ // may change between each use due to recursive layouts.
+ auto menuBarHeight = [this]{ return menuBar && menuBar->isVisible() ? menuBar->height() : 0; };
+ auto headerheight = [this]{ return header && header->isVisible() ? header->height() : 0; };
+ auto footerHeight = [this]{ return footer && footer->isVisible() ? footer->height() : 0; };
control->setSize(q->size());
layoutItem(menuBar, 0, q->width());
- layoutItem(header, menuBarHeight, q->width());
- layoutItem(footer, control->height() - footerHeight, q->width());
+ layoutItem(header, menuBarHeight(), q->width());
+ layoutItem(footer, control->height() - footerHeight(), q->width());
if (background) {
if (!hasBackgroundWidth && qFuzzyIsNull(background->x()))
@@ -168,8 +173,8 @@ void QQuickApplicationWindowPrivate::relayout()
auto *windowSafeArea = static_cast<QQuickSafeArea*>(qmlAttachedPropertiesObject<QQuickSafeArea>(q));
const auto inheritedMargins = windowSafeArea->margins();
controlSafeArea->setAdditionalMargins(QMarginsF(
- 0, (menuBarHeight + headerheight) - inheritedMargins.top(),
- 0, footerHeight - inheritedMargins.bottom()));
+ 0, (menuBarHeight() + headerheight()) - inheritedMargins.top(),
+ 0, footerHeight() - inheritedMargins.bottom()));
}
void QQuickApplicationWindowPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff)