summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/widgets/itemviews/qlistview.cpp26
-rw-r--r--tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp62
2 files changed, 84 insertions, 4 deletions
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index b7a4ec3925..f3fd3e75a1 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1846,8 +1846,17 @@ void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
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()) {
+ const QSize viewportSize(viewport()->width() + (qq->verticalScrollBar()->maximum() > 0 ? qq->verticalScrollBar()->width() : 0),
+ viewport()->height() + (qq->horizontalScrollBar()->maximum() > 0 ? qq->horizontalScrollBar()->height() : 0));
+
+ bool verticalWantsToShow = contentsSize.height() > viewportSize.height();
+ bool horizontalWantsToShow;
+ if (verticalWantsToShow)
+ horizontalWantsToShow = contentsSize.width() > viewportSize.width() - qq->verticalScrollBar()->width();
+ else
+ horizontalWantsToShow = contentsSize.width() > viewportSize.width();
+
+ if (bothScrollBarsAuto && !horizontalWantsToShow) {
// 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);
@@ -1868,8 +1877,17 @@ void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
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()) {
+ const QSize viewportSize(viewport()->width() + (qq->verticalScrollBar()->maximum() > 0 ? qq->verticalScrollBar()->width() : 0),
+ viewport()->height() + (qq->horizontalScrollBar()->maximum() > 0 ? qq->horizontalScrollBar()->height() : 0));
+
+ bool horizontalWantsToShow = contentsSize.width() > viewportSize.width();
+ bool verticalWantsToShow;
+ if (horizontalWantsToShow)
+ verticalWantsToShow = contentsSize.height() > viewportSize.height() - qq->horizontalScrollBar()->height();
+ else
+ verticalWantsToShow = contentsSize.height() > viewportSize.height();
+
+ if (bothScrollBarsAuto && !verticalWantsToShow) {
// 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);
diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
index cea08435c9..32ca5ea7b7 100644
--- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
+++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
@@ -47,6 +47,7 @@
#include <QtWidgets/QScrollBar>
#include <QtWidgets/QDialog>
#include <QtWidgets/QStyledItemDelegate>
+#include <QtWidgets/QStyleFactory>
#if defined(Q_OS_WIN) || defined(Q_OS_WINCE)
# include <windows.h>
@@ -2348,11 +2349,34 @@ void tst_QListView::testViewOptions()
QCOMPARE(options.decorationPosition, QStyleOptionViewItem::Top);
}
+// make sure we have no transient scroll bars
+class TempStyleSetter
+{
+public:
+ TempStyleSetter()
+ : m_oldStyle(qApp->style())
+ {
+ m_oldStyle->setParent(0);
+ QListView tempView;
+ if (QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, tempView.horizontalScrollBar()))
+ QApplication::setStyle(QStyleFactory::create("Fusion"));
+ }
+
+ ~TempStyleSetter()
+ {
+ QApplication::setStyle(m_oldStyle);
+ }
+private:
+ QStyle* m_oldStyle;
+};
+
void tst_QListView::taskQTBUG_39902_mutualScrollBars()
{
QWidget window;
window.resize(400, 300);
QListView *view = new QListView(&window);
+ // make sure we have no transient scroll bars
+ TempStyleSetter styleSetter;
QStandardItemModel model(200, 1);
const QSize itemSize(100, 20);
for (int i = 0; i < model.rowCount(); ++i)
@@ -2370,6 +2394,44 @@ void tst_QListView::taskQTBUG_39902_mutualScrollBars()
view->resize(itemSize.width() + view->frameWidth() * 2, model.rowCount() * itemSize.height() + view->frameWidth() * 2);
// this will end up in a stack overflow, if QTBUG-39902 is not fixed
QTest::qWait(100);
+
+ // these tests do not apply with transient scroll bars enabled
+ QVERIFY (!view->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, view->horizontalScrollBar()));
+
+ // make it double as large, no scroll bars should be visible
+ view->resize((itemSize.width() + view->frameWidth() * 2) * 2, (model.rowCount() * itemSize.height() + view->frameWidth() * 2) * 2);
+ QTRY_VERIFY(!view->horizontalScrollBar()->isVisible());
+ QTRY_VERIFY(!view->verticalScrollBar()->isVisible());
+
+ // make it half the size, both scroll bars should be visible
+ view->resize((itemSize.width() + view->frameWidth() * 2) / 2, (model.rowCount() * itemSize.height() + view->frameWidth() * 2) / 2);
+ QTRY_VERIFY(view->horizontalScrollBar()->isVisible());
+ QTRY_VERIFY(view->verticalScrollBar()->isVisible());
+
+ // make it double as large, no scroll bars should be visible
+ view->resize((itemSize.width() + view->frameWidth() * 2) * 2, (model.rowCount() * itemSize.height() + view->frameWidth() * 2) * 2);
+ QTRY_VERIFY(!view->horizontalScrollBar()->isVisible());
+ QTRY_VERIFY(!view->verticalScrollBar()->isVisible());
+
+ // now, coming from the double size, resize it to the exactly matching size, still no scroll bars should be visible again
+ view->resize(itemSize.width() + view->frameWidth() * 2, model.rowCount() * itemSize.height() + view->frameWidth() * 2);
+ QTRY_VERIFY(!view->horizontalScrollBar()->isVisible());
+ QTRY_VERIFY(!view->verticalScrollBar()->isVisible());
+
+ // now remove just one single pixel in height -> both scroll bars will show up since they depend on each other
+ view->resize(itemSize.width() + view->frameWidth() * 2, model.rowCount() * itemSize.height() + view->frameWidth() * 2 - 1);
+ QTRY_VERIFY(view->horizontalScrollBar()->isVisible());
+ QTRY_VERIFY(view->verticalScrollBar()->isVisible());
+
+ // now remove just one single pixel in with -> both scroll bars will show up since they depend on each other
+ view->resize(itemSize.width() + view->frameWidth() * 2 - 1, model.rowCount() * itemSize.height() + view->frameWidth() * 2);
+ QTRY_VERIFY(view->horizontalScrollBar()->isVisible());
+ QTRY_VERIFY(view->verticalScrollBar()->isVisible());
+
+ // finally, coming from a size being to small, resize back to the exactly matching size -> both scroll bars should disappear again
+ view->resize(itemSize.width() + view->frameWidth() * 2, model.rowCount() * itemSize.height() + view->frameWidth() * 2);
+ QTRY_VERIFY(!view->horizontalScrollBar()->isVisible());
+ QTRY_VERIFY(!view->verticalScrollBar()->isVisible());
}
QTEST_MAIN(tst_QListView)