diff options
author | Lars Knoll <lars.knoll@digia.com> | 2014-09-10 07:39:13 (GMT) |
---|---|---|
committer | Lars Knoll <lars.knoll@digia.com> | 2014-09-10 13:33:21 (GMT) |
commit | 6eb8f6fc66ebf1604457d56ffaeb7020affbb220 (patch) | |
tree | 984ca2e9987ed8bc31bca47e2e3acf87b1b18b79 /src | |
parent | 80e3108f5cd1e1850ec81a21100d79a0946addd7 (diff) | |
download | Qt-6eb8f6fc66ebf1604457d56ffaeb7020affbb220.zip Qt-6eb8f6fc66ebf1604457d56ffaeb7020affbb220.tar.gz Qt-6eb8f6fc66ebf1604457d56ffaeb7020affbb220.tar.bz2 |
QListView: Catch stack overflow on mutual scrollbar calculation.
Backport of fc4993be1fa7673016b6e5d81134463f163051f6 from Qt 5.
Task-number: QTBUG-39902
Task-number: QTBUG-38517
Change-Id: I66b2c7304423dd65d67158ae0dc70ad12e4fa783
Reviewed-by: Christoph Schleifenbaum <christoph.schleifenbaum@kdab.com>
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/itemviews/qlistview.cpp | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index df908e2..ff1bfb3 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -1870,14 +1870,44 @@ void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step) { horizontalScrollBar()->setSingleStep(step.width() + spacing()); horizontalScrollBar()->setPageStep(viewport()->width()); - horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width()); + + // If both scroll bars are set to auto, we might end up in a situation with enough space + // for the actual content. But still one of the scroll bars will become enabled due to + // the other one using the space. The other one will become invisible in the same cycle. + // -> Infinite loop, QTBUG-39902 + const bool bothScrollBarsAuto = qq->verticalScrollBarPolicy() == Qt::ScrollBarAsNeeded && + qq->horizontalScrollBarPolicy() == Qt::ScrollBarAsNeeded; + + if (bothScrollBarsAuto && contentsSize.width() - qq->verticalScrollBar()->width() <= viewport()->width() + && contentsSize.height() - qq->horizontalScrollBar()->height() <= viewport()->height()) { + // break the infinite loop described above by setting the range to 0, 0. + // QAbstractScrollArea will then hide the scroll bar for us + horizontalScrollBar()->setRange(0, 0); + } else { + horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width()); + } } void QCommonListViewBase::updateVerticalScrollBar(const QSize &step) { verticalScrollBar()->setSingleStep(step.height() + spacing()); verticalScrollBar()->setPageStep(viewport()->height()); - verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height()); + + // If both scroll bars are set to auto, we might end up in a situation with enough space + // for the actual content. But still one of the scroll bars will become enabled due to + // the other one using the space. The other one will become invisible in the same cycle. + // -> Infinite loop, QTBUG-39902 + const bool bothScrollBarsAuto = qq->verticalScrollBarPolicy() == Qt::ScrollBarAsNeeded && + qq->horizontalScrollBarPolicy() == Qt::ScrollBarAsNeeded; + + if (bothScrollBarsAuto && contentsSize.width() - qq->verticalScrollBar()->width() <= viewport()->width() + && contentsSize.height() - qq->horizontalScrollBar()->height() <= viewport()->height()) { + // break the infinite loop described above by setting the range to 0, 0. + // QAbstractScrollArea will then hide the scroll bar for us + verticalScrollBar()->setRange(0, 0); + } else { + verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height()); + } } void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/) |