┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/kitemviews/kitemlistcontainer.cpp34
-rw-r--r--src/kitemviews/kitemlistcontainer.h7
-rw-r--r--src/kitemviews/kitemlistview.cpp13
-rw-r--r--src/kitemviews/kitemlistview.h8
4 files changed, 62 insertions, 0 deletions
diff --git a/src/kitemviews/kitemlistcontainer.cpp b/src/kitemviews/kitemlistcontainer.cpp
index 58f2e3cd6..b480b4494 100644
--- a/src/kitemviews/kitemlistcontainer.cpp
+++ b/src/kitemviews/kitemlistcontainer.cpp
@@ -234,11 +234,19 @@ void KItemListContainer::updateScrollOffsetScrollBar()
const int value = view->scrollOffset();
const int maximum = qMax(0, int(view->maximumScrollOffset() - pageStep));
if (smoothScroller->requestScrollBarUpdate(maximum)) {
+ const bool updatePolicy = (scrollOffsetScrollBar->maximum() > 0 && maximum == 0)
+ || horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOn;
+
scrollOffsetScrollBar->setSingleStep(singleStep);
scrollOffsetScrollBar->setPageStep(pageStep);
scrollOffsetScrollBar->setMinimum(0);
scrollOffsetScrollBar->setMaximum(maximum);
scrollOffsetScrollBar->setValue(value);
+
+ if (updatePolicy) {
+ // Prevent a potential endless layout loop (see bug #293318).
+ updateScrollOffsetScrollBarPolicy();
+ }
}
}
@@ -320,6 +328,32 @@ void KItemListContainer::updateSmoothScrollers(Qt::Orientation orientation)
}
}
+void KItemListContainer::updateScrollOffsetScrollBarPolicy()
+{
+ const KItemListView* view = m_controller->view();
+ Q_ASSERT(view);
+ const bool vertical = (view->scrollOrientation() == Qt::Vertical);
+
+ QStyleOption option;
+ option.initFrom(this);
+ const int scrollBarInc = style()->pixelMetric(QStyle::PM_ScrollBarExtent, &option, this);
+
+ QSizeF newViewSize = m_controller->view()->size();
+ if (vertical) {
+ newViewSize.rwidth() += scrollBarInc;
+ } else {
+ newViewSize.rheight() += scrollBarInc;
+ }
+
+ const Qt::ScrollBarPolicy policy = view->scrollBarRequired(newViewSize)
+ ? Qt::ScrollBarAlwaysOn : Qt::ScrollBarAsNeeded;
+ if (vertical) {
+ setVerticalScrollBarPolicy(policy);
+ } else {
+ setHorizontalScrollBarPolicy(policy);
+ }
+}
+
void KItemListContainer::initialize()
{
if (m_controller) {
diff --git a/src/kitemviews/kitemlistcontainer.h b/src/kitemviews/kitemlistcontainer.h
index 4d6eadbbb..b41f48a7f 100644
--- a/src/kitemviews/kitemlistcontainer.h
+++ b/src/kitemviews/kitemlistcontainer.h
@@ -70,6 +70,13 @@ private:
void updateGeometries();
void updateSmoothScrollers(Qt::Orientation orientation);
+ /**
+ * Helper method for updateScrollOffsetScrollBar(). Updates the scrollbar-policy
+ * to Qt::ScrollBarAlwaysOn for cases where turning off the scrollbar might lead
+ * to an endless layout loop (see bug #293318).
+ */
+ void updateScrollOffsetScrollBarPolicy();
+
private:
KItemListController* m_controller;
diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp
index c671a2e6e..52d857705 100644
--- a/src/kitemviews/kitemlistview.cpp
+++ b/src/kitemviews/kitemlistview.cpp
@@ -1880,6 +1880,19 @@ bool KItemListView::animateChangedItemCount(int changedItemCount) const
return changedItemCount <= maximum * 2 / 3;
}
+
+bool KItemListView::scrollBarRequired(const QSizeF& size) const
+{
+ const QSizeF oldSize = m_layouter->size();
+
+ m_layouter->setSize(size);
+ const qreal maxOffset = m_layouter->maximumScrollOffset();
+ m_layouter->setSize(oldSize);
+
+ return m_layouter->scrollOrientation() == Qt::Vertical ? maxOffset > size.height()
+ : maxOffset > size.width();
+}
+
int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldInc)
{
int inc = 0;
diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h
index 9c34daba3..e675df221 100644
--- a/src/kitemviews/kitemlistview.h
+++ b/src/kitemviews/kitemlistview.h
@@ -462,6 +462,13 @@ private:
bool animateChangedItemCount(int changedItemCount) const;
/**
+ * @return True if a scrollbar for the given scroll-orientation is required
+ * when using a size of \p size for the view. Calling the method is rather
+ * expansive as a temporary relayout needs to be done.
+ */
+ bool scrollBarRequired(const QSizeF& size) const;
+
+ /**
* Helper function for triggerAutoScrolling().
* @param pos Logical position of the mouse relative to the range.
* @param range Range of the visible area.
@@ -512,6 +519,7 @@ private:
KItemListHeader* m_header;
bool m_useHeaderWidths;
+ friend class KItemListContainer; // Accesses scrollBarRequired()
friend class KItemListController;
friend class KItemListControllerTest;
};