aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@qt.io>2019-02-19 14:22:27 +0100
committerMitch Curtis <mitch.curtis@qt.io>2019-02-20 14:33:05 +0000
commit16836da1ae44c11317b9861764ea55cce39eac02 (patch)
tree9b7426680516b54e409ab94a437f9e14fdd15db9
parent0dfc617e4d089f7513573673d12f9678a88d3081 (diff)
Page: fix binding loop
When Dialog (which derives from Page) has only its title set, there'd be a binding loop. A simplified version of the call stack: - QQuickPopup::componentComplete - QQuickPopupPrivate::prepareEnterTransition - QQuickItem::setVisible - QQuickPagePrivate::itemVisibilityChanged - QQuickDialog::implicitHeaderWidthChanged - QQmlBinding::expressionChanged <== Dialog.qml's implicitWidth binding - QQmlPropertyData::readProperty - QQuickDialog::implicitHeaderWidth - QQuickPage::implicitHeaderWidth - QQuickItem::implicitWidth <== QQuickPagePrivate::header, aka Label - QQuickTextPrivate::getImplicitWidth - QQuickTextPrivate::updateSize - QQuickTextPrivate::setupTextLayout - QQuickItem::setImplicitSize - QQuickItemPrivate::implicitWidthChanged - QQuickPagePrivate::itemImplicitWidthChanged - QQuickDialog::implicitHeaderWidthChanged - QQmlBinding::expressionChanged - QQmlAbstractBinding::printBindingLoopError Fix the issue by not emitting change signals if we're already in the process of doing so. Change-Id: I37d6fa35b1e70420e436c0e001f55035d7630542 Fixes: QTBUG-66494 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
-rw-r--r--src/quicktemplates2/qquickpage.cpp12
-rw-r--r--src/quicktemplates2/qquickpage_p_p.h1
2 files changed, 13 insertions, 0 deletions
diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp
index 56034297..cb90ac48 100644
--- a/src/quicktemplates2/qquickpage.cpp
+++ b/src/quicktemplates2/qquickpage.cpp
@@ -149,10 +149,12 @@ void QQuickPagePrivate::itemVisibilityChanged(QQuickItem *item)
Q_Q(QQuickPage);
QQuickPanePrivate::itemVisibilityChanged(item);
if (item == header) {
+ QBoolBlocker signalGuard(emittingImplicitSizeChangedSignals);
emit q->implicitHeaderWidthChanged();
emit q->implicitHeaderHeightChanged();
relayout();
} else if (item == footer) {
+ QBoolBlocker signalGuard(emittingImplicitSizeChangedSignals);
emit q->implicitFooterWidthChanged();
emit q->implicitFooterHeightChanged();
relayout();
@@ -163,6 +165,11 @@ void QQuickPagePrivate::itemImplicitWidthChanged(QQuickItem *item)
{
Q_Q(QQuickPage);
QQuickPanePrivate::itemImplicitWidthChanged(item);
+
+ // Avoid binding loops by skipping signal emission if we're already doing it.
+ if (emittingImplicitSizeChangedSignals)
+ return;
+
if (item == header)
emit q->implicitHeaderWidthChanged();
else if (item == footer)
@@ -173,6 +180,11 @@ void QQuickPagePrivate::itemImplicitHeightChanged(QQuickItem *item)
{
Q_Q(QQuickPage);
QQuickPanePrivate::itemImplicitHeightChanged(item);
+
+ // Avoid binding loops by skipping signal emission if we're already doing it.
+ if (emittingImplicitSizeChangedSignals)
+ return;
+
if (item == header)
emit q->implicitHeaderHeightChanged();
else if (item == footer)
diff --git a/src/quicktemplates2/qquickpage_p_p.h b/src/quicktemplates2/qquickpage_p_p.h
index b7d89ac4..6c8b0371 100644
--- a/src/quicktemplates2/qquickpage_p_p.h
+++ b/src/quicktemplates2/qquickpage_p_p.h
@@ -71,6 +71,7 @@ public:
QString title;
QQuickItem *header = nullptr;
QQuickItem *footer = nullptr;
+ bool emittingImplicitSizeChangedSignals = false;
};
QT_END_NAMESPACE