Fix menu position when highdpi scaling

Certain display and scale factor configurations would
cause menus to pop up in incorrect locations or not
be shown at all.

This was due to QDesktopWidget::screenNumber() having
a toNativePixels(QRect, QWindow) call which requires
that QWindow::screen() returns the correct screen.

Break the circular dependency by converting coordinates
the other way for the intersection test: transform screen
geometry to device independent coordinates.

Task-number: QTBUG-58329
Change-Id: I5621de89a9a2b8df44bdae528baf011fc111eba3
Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Morten Johan Sørvig 2017-04-05 12:39:15 +02:00
parent efb84b6189
commit 5e76cb1692

View File

@ -269,12 +269,13 @@ int QDesktopWidget::screenNumber(const QWidget *w) const
QRect frame = w->frameGeometry(); QRect frame = w->frameGeometry();
if (!w->isWindow()) if (!w->isWindow())
frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0))); frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0)));
const QRect nativeFrame = QHighDpi::toNativePixels(frame, winHandle);
QScreen *widgetScreen = Q_NULLPTR; QScreen *widgetScreen = Q_NULLPTR;
int largestArea = 0; int largestArea = 0;
foreach (QScreen *screen, screens) { foreach (QScreen *screen, screens) {
const QRect intersected = screen->handle()->geometry().intersected(nativeFrame); const QRect deviceIndependentScreenGeometry =
QHighDpi::fromNativePixels(screen->handle()->geometry(), screen);
const QRect intersected = deviceIndependentScreenGeometry.intersected(frame);
int area = intersected.width() * intersected.height(); int area = intersected.width() * intersected.height();
if (largestArea < area) { if (largestArea < area) {
widgetScreen = screen; widgetScreen = screen;