Display combobox popup on the correct screen

Display QCompoBox popups on the correct screen, also
when the parent window spans multiple screens. In this
case, QWidget::screen() will return the main screen for the
window, which will not necessarily be the screen at
the combobox popup position.

Change-Id: Ib8a8163a757f7b849883b833fbde27a1e01af49a
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Morten Johan Sørvig 2020-08-21 16:20:31 +02:00
parent a646bcf2be
commit 707b64bece
3 changed files with 40 additions and 12 deletions

View File

@ -51,6 +51,8 @@
// We mean it.
//
#include <QtWidgets/private/qtwidgetsglobal_p.h>
#include "QtWidgets/qwidget.h"
#include "private/qobject_p.h"
@ -498,19 +500,45 @@ public:
#endif
return rect;
}
static QRect screenGeometry(const QWidget *widget)
{
QRect rect = graphicsViewParentRect(widget);
if (rect.isNull())
rect = widget->screen()->geometry();
return rect;
return screenGeometry(widget, QPoint(), false);
}
static QRect availableScreenGeometry(const QWidget *widget)
{
return availableScreenGeometry(widget, QPoint(), false);
}
static QRect screenGeometry(const QWidget *widget, const QPoint &globalPosition, bool hasPosition = true)
{
QRect rect = graphicsViewParentRect(widget);
if (rect.isNull())
rect = widget->screen()->availableGeometry();
return rect;
if (!rect.isNull())
return rect;
QScreen *screen = nullptr;
if (hasPosition)
screen = widget->screen()->virtualSiblingAt(globalPosition);
if (!screen)
screen = widget->screen();
return screen->geometry();
}
static QRect availableScreenGeometry(const QWidget *widget, const QPoint &globalPosition, bool hasPosition = true)
{
QRect rect = graphicsViewParentRect(widget);
if (!rect.isNull())
return rect;
QScreen *screen = nullptr;
if (hasPosition)
screen = widget->screen()->virtualSiblingAt(globalPosition);
if (!screen)
screen = widget->screen();
return screen->availableGeometry();
}
inline void setRedirected(QPaintDevice *replacement, const QPoint &offset)

View File

@ -319,12 +319,12 @@ void QComboBoxPrivate::trySetValidIndex()
setCurrentIndex(QModelIndex());
}
QRect QComboBoxPrivate::popupGeometry() const
QRect QComboBoxPrivate::popupGeometry(const QPoint &globalPosition) const
{
Q_Q(const QComboBox);
return QStylePrivate::useFullScreenForPopup()
? QWidgetPrivate::screenGeometry(q)
: QWidgetPrivate::availableScreenGeometry(q);
? QWidgetPrivate::screenGeometry(q, globalPosition)
: QWidgetPrivate::availableScreenGeometry(q, globalPosition);
}
bool QComboBoxPrivate::updateHoverControl(const QPoint &pos)
@ -2612,7 +2612,7 @@ void QComboBox::showPopup()
QComboBoxPrivateContainer* container = d->viewContainer();
QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt,
QStyle::SC_ComboBoxListBoxPopup, this));
QRect screen = d->popupGeometry();
QRect screen = d->popupGeometry(mapToGlobal(listRect.topLeft()));
QPoint below = mapToGlobal(listRect.bottomLeft());
int belowHeight = screen.bottom() - below.y();

View File

@ -371,7 +371,7 @@ public:
void updateArrow(QStyle::StateFlag state);
bool updateHoverControl(const QPoint &pos);
void trySetValidIndex();
QRect popupGeometry() const;
QRect popupGeometry(const QPoint &globalPos) const;
QStyle::SubControl newHoverControl(const QPoint &pos);
int computeWidthHint() const;
QSize recomputeSizeHint(QSize &sh) const;