summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Shaw <andy.shaw@qt.io>2017-12-12 15:53:44 +0100
committerPaul Olav Tvete <paul.tvete@qt.io>2017-12-18 11:10:48 +0000
commit3841a7dd49667ceabdcbc416fa1e149bed7ed86e (patch)
tree1e12ae5582a5e4c4468be2e372b2b99844ca490f
parent93dabeba9dc5f6cbab60e65b3cc8df5fe48745a9 (diff)
Prevent infinite relayout when adding scrollbars
When one scrollbar is added, this may cause the other to be needed as well. This change does a second calculation immediately instead of relying on a signal through a QueuedConnection. Task-number: QTBUG-62818 Task-number: QTBUG-56280 Change-Id: Iee9a083e3a6cd3765e6bb9206687a8a6e7f99cff Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp25
-rw-r--r--src/widgets/widgets/qabstractscrollarea_p.h1
2 files changed, 20 insertions, 6 deletions
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 249ebd35d3..c6d66bafd4 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -334,16 +334,27 @@ void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on)
void QAbstractScrollAreaPrivate::layoutChildren()
{
+ bool needH = false;
+ bool needV = false;
+ layoutChildren_helper(&needH, &needV);
+ // Call a second time if one scrollbar was needed and not the other to
+ // check if it needs to readjust accordingly
+ if (needH != needV)
+ layoutChildren_helper(&needH, &needV);
+}
+
+void QAbstractScrollAreaPrivate::layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar)
+{
Q_Q(QAbstractScrollArea);
bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, hbar);
- bool needh = (hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
- || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
- && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty()));
+ bool needh = *needHorizontalScrollbar || ((hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
+ || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
+ && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty())));
bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar);
- bool needv = (vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
- || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
- && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty()));
+ bool needv = *needVerticalScrollbar || ((vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
+ || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
+ && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty())));
QStyleOption opt(0);
opt.init(q);
@@ -522,6 +533,8 @@ void QAbstractScrollAreaPrivate::layoutChildren()
viewportRect.adjust(left, top, -right, -bottom);
viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last
+ *needHorizontalScrollbar = needh;
+ *needVerticalScrollbar = needv;
}
/*!
diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h
index c52e7f9fd4..49f97bcb61 100644
--- a/src/widgets/widgets/qabstractscrollarea_p.h
+++ b/src/widgets/widgets/qabstractscrollarea_p.h
@@ -95,6 +95,7 @@ public:
void init();
void layoutChildren();
+ void layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar);
// ### Fix for 4.4, talk to Bjoern E or Girish.
virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
bool canStartScrollingAt( const QPoint &startPos );