From 7af39fb960352e0504153c627db0615d80758ebe Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sun, 5 Feb 2012 19:14:17 +0100 Subject: Fix potential endless loop in layout Usecase: - No scrollbar is shown - Window size will be decreased so that a scrollbar gets necessary The decreased window size minus the space required for the scrollbar results in a relayout of the items. In 99 % of all cases a decreased window size won't result in showing more items in parallel in comparison to a larger window size. However in the remaining 1 % this can happen (e.g. see bug 293318 for a sample). This results in an endless loop as now no scrollbar is required anymore, the layout changes again, the scrollbar is required again, ... BUG: 293318 FIXED-IN: 4.8.1 --- src/kitemviews/kitemlistcontainer.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/kitemviews/kitemlistcontainer.cpp') 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) { -- cgit v1.3