diff options
author | Andy Shaw <andy.shaw@qt.io> | 2017-12-12 15:53:44 +0100 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2017-12-18 11:10:48 +0000 |
commit | 3841a7dd49667ceabdcbc416fa1e149bed7ed86e (patch) | |
tree | 1e12ae5582a5e4c4468be2e372b2b99844ca490f | |
parent | 93dabeba9dc5f6cbab60e65b3cc8df5fe48745a9 (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.cpp | 25 | ||||
-rw-r--r-- | src/widgets/widgets/qabstractscrollarea_p.h | 1 |
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 ); |