QComboBox: add space for scrollbar if needed after showing popup

QComboBox tests if a horizontal scrollbar is needed before sizing and
showing the popup, but QListView only knows whether a scrollbar is needed
only after laying itself out during the initial show and paint event.

So test whether the need has arisen as part of this initial layout, and
then provide the additional space. Resizing the widget after showing it
is not ideal, but in practice makes no visible difference (and it's
either way preferable to not being able to access the item covered by
the scrollbar).

Pick-to: 6.1 5.15
Fixes: QTBUG-93736
Change-Id: I0bf077e18116ce174ae7f9218cb3b0dfa82964e1
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
Volker Hilsheimer 2021-05-25 18:11:10 +02:00
parent cbd226fffa
commit 11e88eaa6d

View File

@ -2741,13 +2741,15 @@ void QComboBox::showPopup()
QGuiApplication::inputMethod()->reset();
}
QScrollBar *sb = view()->horizontalScrollBar();
Qt::ScrollBarPolicy policy = view()->horizontalScrollBarPolicy();
bool needHorizontalScrollBar = (policy == Qt::ScrollBarAsNeeded || policy == Qt::ScrollBarAlwaysOn)
&& sb->minimum() < sb->maximum();
if (needHorizontalScrollBar) {
const QScrollBar *sb = view()->horizontalScrollBar();
const auto needHorizontalScrollBar = [this, sb]{
const Qt::ScrollBarPolicy policy = view()->horizontalScrollBarPolicy();
return (policy == Qt::ScrollBarAsNeeded || policy == Qt::ScrollBarAlwaysOn)
&& sb->minimum() < sb->maximum();
};
const bool neededHorizontalScrollBar = needHorizontalScrollBar();
if (neededHorizontalScrollBar)
listRect.adjust(0, 0, 0, sb->height());
}
// Hide the scrollers here, so that the listrect gets the full height of the container
// If the scrollers are truly needed, the later call to container->updateScrollers()
@ -2790,6 +2792,11 @@ void QComboBox::showPopup()
}
}
container->show();
if (!neededHorizontalScrollBar && needHorizontalScrollBar()) {
listRect.adjust(0, 0, 0, sb->height());
container->setGeometry(listRect);
}
container->updateScrollers();
view()->setFocus();