diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-10-07 17:56:37 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-10-11 10:49:57 +0200 |
commit | 6c4dc722cb9bf765904feefff4fb00bdb0b3dc9f (patch) | |
tree | 49b1d6c5bb48c9dda1b091739f25ee8104104dfb /src/widgets | |
parent | dd57605b9ef4e12805868962efce586e57e342b6 (diff) |
Reduce the width of a hfw-widget if scrollbar would be flipping
For a widget that implements height-for-width, the vertical scrollbar
becoming visible might be just enough to make the scrollbar unnecessary.
In that situation, the scrollbar flips on and off continuously.
To avoid that situation, make the width of the widget smaller until the
height fits without scrollbar, up to the point where we have space for
the scrollbar anyway.
The calcuation here is assumed to be cheap, but depends on the
heightForWidth implementation in the widget. Running the while-loop a
few dozen times should have no performance impact during resizing
and laying out the scroll area contents.
Add a test that confirms that within a brief period of time we only get
the one hide-event we expect.
Done-with: Zou Ya <zouya@uniontech.com>
Fixes: QTBUG-92958
Pick-to: 6.2 5.15
Change-Id: I0faeb5f9b1a226aada958c18333d9c2ac8203dd1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/widgets/qscrollarea.cpp | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp index f7a4f8e446..f880240ea7 100644 --- a/src/widgets/widgets/qscrollarea.cpp +++ b/src/widgets/widgets/qscrollarea.cpp @@ -196,7 +196,20 @@ void QScrollAreaPrivate::updateScrollBars() if (resizable) { if ((widget->layout() ? widget->layout()->hasHeightForWidth() : widget->sizePolicy().hasHeightForWidth())) { QSize p_hfw = p.expandedTo(min).boundedTo(max); - int h = widget->heightForWidth( p_hfw.width() ); + int h = widget->heightForWidth(p_hfw.width()); + // If the height we calculated requires a vertical scrollbar, + // then we need to constrain the width and calculate the height again, + // otherwise we end up flipping the scrollbar on and off all the time. + if (vbarpolicy == Qt::ScrollBarAsNeeded) { + int vbarWidth = vbar->sizeHint().width(); + QSize m_hfw = m.expandedTo(min).boundedTo(max); + while (h > m.height() && vbarWidth) { + --vbarWidth; + --m_hfw.rwidth(); + h = widget->heightForWidth(m_hfw.width()); + } + max = QSize(m_hfw.width(), qMax(m_hfw.height(), h)); + } min = QSize(p_hfw.width(), qMax(p_hfw.height(), h)); } } |