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>
This commit is contained in:
parent
93dabeba9d
commit
3841a7dd49
@ -333,17 +333,28 @@ void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void QAbstractScrollAreaPrivate::layoutChildren()
|
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);
|
Q_Q(QAbstractScrollArea);
|
||||||
bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, hbar);
|
bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, hbar);
|
||||||
bool needh = (hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
|
bool needh = *needHorizontalScrollbar || ((hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
|
||||||
|| ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
|
|| ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
|
||||||
&& hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty()));
|
&& hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty())));
|
||||||
|
|
||||||
bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar);
|
bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar);
|
||||||
bool needv = (vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
|
bool needv = *needVerticalScrollbar || ((vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
|
||||||
|| ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
|
|| ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
|
||||||
&& vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty()));
|
&& vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty())));
|
||||||
|
|
||||||
QStyleOption opt(0);
|
QStyleOption opt(0);
|
||||||
opt.init(q);
|
opt.init(q);
|
||||||
@ -522,6 +533,8 @@ void QAbstractScrollAreaPrivate::layoutChildren()
|
|||||||
viewportRect.adjust(left, top, -right, -bottom);
|
viewportRect.adjust(left, top, -right, -bottom);
|
||||||
|
|
||||||
viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last
|
viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last
|
||||||
|
*needHorizontalScrollbar = needh;
|
||||||
|
*needVerticalScrollbar = needv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -95,6 +95,7 @@ public:
|
|||||||
|
|
||||||
void init();
|
void init();
|
||||||
void layoutChildren();
|
void layoutChildren();
|
||||||
|
void layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar);
|
||||||
// ### Fix for 4.4, talk to Bjoern E or Girish.
|
// ### Fix for 4.4, talk to Bjoern E or Girish.
|
||||||
virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
|
virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
|
||||||
bool canStartScrollingAt( const QPoint &startPos );
|
bool canStartScrollingAt( const QPoint &startPos );
|
||||||
|
Loading…
Reference in New Issue
Block a user