diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 2a0cb1094c..65accc9f68 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -694,9 +694,12 @@ static QSize fixInitialSize(QSize size, const QWindow *w, However if the given window already has geometry which the application has initialized, it takes priority. */ -QRect QPlatformWindow::initialGeometry(const QWindow *w, - const QRect &initialGeometry, int defaultWidth, int defaultHeight) +QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeometry, + int defaultWidth, int defaultHeight, + const QScreen **resultingScreenReturn) { + if (resultingScreenReturn) + *resultingScreenReturn = w->screen(); if (!w->isTopLevel()) { const qreal factor = QHighDpiScaling::factor(w); const QSize size = fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor), @@ -712,6 +715,8 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w, : QGuiApplication::screenAt(initialGeometry.center()); if (!screen) return initialGeometry; + if (resultingScreenReturn) + *resultingScreenReturn = screen; // initialGeometry refers to window's screen QRect rect(QHighDpi::fromNativePixels(initialGeometry, w)); if (wp->resizeAutomatic) diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 4d48cc2f13..b6aeb3a86a 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE class QPlatformScreen; class QPlatformWindowPrivate; +class QScreen; class QWindow; class QIcon; class QRegion; @@ -142,8 +143,9 @@ public: virtual void invalidateSurface(); - static QRect initialGeometry(const QWindow *w, - const QRect &initialGeometry, int defaultWidth, int defaultHeight); + static QRect initialGeometry(const QWindow *w, const QRect &initialGeometry, + int defaultWidth, int defaultHeight, + const QScreen **resultingScreenReturn = nullptr); virtual void requestUpdate(); bool hasPendingUpdateRequest() const; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index a4f4099aa6..ea91e3bb2d 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -759,7 +759,10 @@ QWindowsWindowData const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w); - const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, defaultWindowWidth, defaultWindowHeight); + const QScreen *screen{}; + const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, + defaultWindowWidth, defaultWindowHeight, + &screen); if (title.isEmpty() && (result.flags & Qt::WindowTitleHint)) title = topLevel ? qAppName() : w->objectName(); @@ -769,7 +772,9 @@ QWindowsWindowData // Capture events before CreateWindowEx() returns. The context is cleared in // the QWindowsWindow constructor. - const QWindowCreationContextPtr context(new QWindowCreationContext(w, data.geometry, rect, data.customMargins, style, exStyle)); + const QWindowCreationContextPtr context(new QWindowCreationContext(w, screen, data.geometry, + rect, data.customMargins, + style, exStyle)); QWindowsContext::instance()->setWindowCreationContext(context); const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME)); @@ -879,10 +884,10 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang // Scaling helpers for size constraints. -static QSize toNativeSizeConstrained(QSize dip, const QWindow *w) +static QSize toNativeSizeConstrained(QSize dip, const QScreen *s) { if (QHighDpiScaling::isActive()) { - const qreal factor = QHighDpiScaling::factor(w); + const qreal factor = QHighDpiScaling::factor(s); if (!qFuzzyCompare(factor, qreal(1))) { if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX) dip.setWidth(qRound(qreal(dip.width()) * factor)); @@ -995,11 +1000,12 @@ bool QWindowsGeometryHint::handleCalculateSize(const QMargins &customMargins, co return true; } -void QWindowsGeometryHint::frameSizeConstraints(const QWindow *w, const QMargins &margins, +void QWindowsGeometryHint::frameSizeConstraints(const QWindow *w, const QScreen *screen, + const QMargins &margins, QSize *minimumSize, QSize *maximumSize) { - *minimumSize = toNativeSizeConstrained(w->minimumSize(), w); - *maximumSize = toNativeSizeConstrained(w->maximumSize(), w); + *minimumSize = toNativeSizeConstrained(w->minimumSize(), screen); + *maximumSize = toNativeSizeConstrained(w->maximumSize(), screen); const int maximumWidth = qMax(maximumSize->width(), minimumSize->width()); const int maximumHeight = qMax(maximumSize->height(), minimumSize->height()); @@ -1017,12 +1023,13 @@ void QWindowsGeometryHint::frameSizeConstraints(const QWindow *w, const QMargins } void QWindowsGeometryHint::applyToMinMaxInfo(const QWindow *w, + const QScreen *screen, const QMargins &margins, MINMAXINFO *mmi) { QSize minimumSize; QSize maximumSize; - frameSizeConstraints(w, margins, &minimumSize, &maximumSize); + frameSizeConstraints(w, screen, margins, &minimumSize, &maximumSize); qCDebug(lcQpaWindows).nospace() << '>' << __FUNCTION__ << '<' << " min=" << minimumSize.width() << ',' << minimumSize.height() << " max=" << maximumSize.width() << ',' << maximumSize.height() @@ -1041,6 +1048,13 @@ void QWindowsGeometryHint::applyToMinMaxInfo(const QWindow *w, qCDebug(lcQpaWindows).nospace() << '<' << __FUNCTION__ << " out " << *mmi; } +void QWindowsGeometryHint::applyToMinMaxInfo(const QWindow *w, + const QMargins &margins, + MINMAXINFO *mmi) +{ + applyToMinMaxInfo(w, w->screen(), margins, mmi); +} + bool QWindowsGeometryHint::positionIncludesFrame(const QWindow *w) { return qt_window_private(const_cast(w))->positionPolicy @@ -1226,11 +1240,12 @@ void QWindowsForeignWindow::setVisible(bool visible) \ingroup qt-lighthouse-win */ -QWindowCreationContext::QWindowCreationContext(const QWindow *w, +QWindowCreationContext::QWindowCreationContext(const QWindow *w, const QScreen *s, const QRect &geometryIn, const QRect &geometry, const QMargins &cm, DWORD style, DWORD exStyle) : window(w), + screen(s), requestedGeometryIn(geometryIn), requestedGeometry(geometry), obtainedPos(geometryIn.topLeft()), @@ -1270,7 +1285,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, void QWindowCreationContext::applyToMinMaxInfo(MINMAXINFO *mmi) const { - QWindowsGeometryHint::applyToMinMaxInfo(window, margins + customMargins, mmi); + QWindowsGeometryHint::applyToMinMaxInfo(window, screen, margins + customMargins, mmi); } /*! diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 7efbcf900c..1f8800272b 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -66,9 +66,12 @@ struct QWindowsGeometryHint static QMargins frame(const QWindow *w, const QRect &geometry, DWORD style, DWORD exStyle); static bool handleCalculateSize(const QMargins &customMargins, const MSG &msg, LRESULT *result); + static void applyToMinMaxInfo(const QWindow *w, const QScreen *screen, + const QMargins &margins, MINMAXINFO *mmi); static void applyToMinMaxInfo(const QWindow *w, const QMargins &margins, MINMAXINFO *mmi); - static void frameSizeConstraints(const QWindow *w, const QMargins &margins, + static void frameSizeConstraints(const QWindow *w, const QScreen *screen, + const QMargins &margins, QSize *minimumSize, QSize *maximumSize); static inline QPoint mapToGlobal(HWND hwnd, const QPoint &); static inline QPoint mapToGlobal(const QWindow *w, const QPoint &); @@ -80,13 +83,16 @@ struct QWindowsGeometryHint struct QWindowCreationContext { - explicit QWindowCreationContext(const QWindow *w, + explicit QWindowCreationContext(const QWindow *w, const QScreen *s, const QRect &geometryIn, const QRect &geometry, const QMargins &customMargins, DWORD style, DWORD exStyle); void applyToMinMaxInfo(MINMAXINFO *mmi) const; const QWindow *window; + // The screen to use to scale size constraints, etc. Might differ from the + // screen of the window after QPlatformWindow::initialGeometry() (QTBUG-77307). + const QScreen *screen; QRect requestedGeometryIn; // QWindow scaled QRect requestedGeometry; // after QPlatformWindow::initialGeometry() QPoint obtainedPos;