Windows QPA: Fix wrong scaling of fixed size in window creation phase
When a fixed size the window is moved to another screen by QPlatformWindow::initialGeometry(), the size constraints would be incorrectly scaled using the initial screen in the handling of WM_GETMINMAXINFO. To fix this, pass the resulting screen out of QPlatformWindow::initialGeometry() and use it during the window creation phase. Fixes: QTBUG-77307 Change-Id: I149a2a65e816da841a32abc14a495925bf9cc6f6 Reviewed-by: André de la Rocha <andre.rocha@qt.io> Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
parent
1dd83dd202
commit
8f2db974ab
@ -694,9 +694,12 @@ static QSize fixInitialSize(QSize size, const QWindow *w,
|
|||||||
However if the given window already has geometry which the application has
|
However if the given window already has geometry which the application has
|
||||||
initialized, it takes priority.
|
initialized, it takes priority.
|
||||||
*/
|
*/
|
||||||
QRect QPlatformWindow::initialGeometry(const QWindow *w,
|
QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeometry,
|
||||||
const QRect &initialGeometry, int defaultWidth, int defaultHeight)
|
int defaultWidth, int defaultHeight,
|
||||||
|
const QScreen **resultingScreenReturn)
|
||||||
{
|
{
|
||||||
|
if (resultingScreenReturn)
|
||||||
|
*resultingScreenReturn = w->screen();
|
||||||
if (!w->isTopLevel()) {
|
if (!w->isTopLevel()) {
|
||||||
const qreal factor = QHighDpiScaling::factor(w);
|
const qreal factor = QHighDpiScaling::factor(w);
|
||||||
const QSize size = fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor),
|
const QSize size = fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor),
|
||||||
@ -712,6 +715,8 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
|
|||||||
: QGuiApplication::screenAt(initialGeometry.center());
|
: QGuiApplication::screenAt(initialGeometry.center());
|
||||||
if (!screen)
|
if (!screen)
|
||||||
return initialGeometry;
|
return initialGeometry;
|
||||||
|
if (resultingScreenReturn)
|
||||||
|
*resultingScreenReturn = screen;
|
||||||
// initialGeometry refers to window's screen
|
// initialGeometry refers to window's screen
|
||||||
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
|
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
|
||||||
if (wp->resizeAutomatic)
|
if (wp->resizeAutomatic)
|
||||||
|
@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
class QPlatformScreen;
|
class QPlatformScreen;
|
||||||
class QPlatformWindowPrivate;
|
class QPlatformWindowPrivate;
|
||||||
|
class QScreen;
|
||||||
class QWindow;
|
class QWindow;
|
||||||
class QIcon;
|
class QIcon;
|
||||||
class QRegion;
|
class QRegion;
|
||||||
@ -142,8 +143,9 @@ public:
|
|||||||
|
|
||||||
virtual void invalidateSurface();
|
virtual void invalidateSurface();
|
||||||
|
|
||||||
static QRect initialGeometry(const QWindow *w,
|
static QRect initialGeometry(const QWindow *w, const QRect &initialGeometry,
|
||||||
const QRect &initialGeometry, int defaultWidth, int defaultHeight);
|
int defaultWidth, int defaultHeight,
|
||||||
|
const QScreen **resultingScreenReturn = nullptr);
|
||||||
|
|
||||||
virtual void requestUpdate();
|
virtual void requestUpdate();
|
||||||
bool hasPendingUpdateRequest() const;
|
bool hasPendingUpdateRequest() const;
|
||||||
|
@ -759,7 +759,10 @@ QWindowsWindowData
|
|||||||
|
|
||||||
const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w);
|
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))
|
if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
|
||||||
title = topLevel ? qAppName() : w->objectName();
|
title = topLevel ? qAppName() : w->objectName();
|
||||||
@ -769,7 +772,9 @@ QWindowsWindowData
|
|||||||
|
|
||||||
// Capture events before CreateWindowEx() returns. The context is cleared in
|
// Capture events before CreateWindowEx() returns. The context is cleared in
|
||||||
// the QWindowsWindow constructor.
|
// 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);
|
QWindowsContext::instance()->setWindowCreationContext(context);
|
||||||
|
|
||||||
const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME));
|
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.
|
// Scaling helpers for size constraints.
|
||||||
static QSize toNativeSizeConstrained(QSize dip, const QWindow *w)
|
static QSize toNativeSizeConstrained(QSize dip, const QScreen *s)
|
||||||
{
|
{
|
||||||
if (QHighDpiScaling::isActive()) {
|
if (QHighDpiScaling::isActive()) {
|
||||||
const qreal factor = QHighDpiScaling::factor(w);
|
const qreal factor = QHighDpiScaling::factor(s);
|
||||||
if (!qFuzzyCompare(factor, qreal(1))) {
|
if (!qFuzzyCompare(factor, qreal(1))) {
|
||||||
if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX)
|
if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX)
|
||||||
dip.setWidth(qRound(qreal(dip.width()) * factor));
|
dip.setWidth(qRound(qreal(dip.width()) * factor));
|
||||||
@ -995,11 +1000,12 @@ bool QWindowsGeometryHint::handleCalculateSize(const QMargins &customMargins, co
|
|||||||
return true;
|
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)
|
QSize *minimumSize, QSize *maximumSize)
|
||||||
{
|
{
|
||||||
*minimumSize = toNativeSizeConstrained(w->minimumSize(), w);
|
*minimumSize = toNativeSizeConstrained(w->minimumSize(), screen);
|
||||||
*maximumSize = toNativeSizeConstrained(w->maximumSize(), w);
|
*maximumSize = toNativeSizeConstrained(w->maximumSize(), screen);
|
||||||
|
|
||||||
const int maximumWidth = qMax(maximumSize->width(), minimumSize->width());
|
const int maximumWidth = qMax(maximumSize->width(), minimumSize->width());
|
||||||
const int maximumHeight = qMax(maximumSize->height(), minimumSize->height());
|
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,
|
void QWindowsGeometryHint::applyToMinMaxInfo(const QWindow *w,
|
||||||
|
const QScreen *screen,
|
||||||
const QMargins &margins,
|
const QMargins &margins,
|
||||||
MINMAXINFO *mmi)
|
MINMAXINFO *mmi)
|
||||||
{
|
{
|
||||||
QSize minimumSize;
|
QSize minimumSize;
|
||||||
QSize maximumSize;
|
QSize maximumSize;
|
||||||
frameSizeConstraints(w, margins, &minimumSize, &maximumSize);
|
frameSizeConstraints(w, screen, margins, &minimumSize, &maximumSize);
|
||||||
qCDebug(lcQpaWindows).nospace() << '>' << __FUNCTION__ << '<' << " min="
|
qCDebug(lcQpaWindows).nospace() << '>' << __FUNCTION__ << '<' << " min="
|
||||||
<< minimumSize.width() << ',' << minimumSize.height()
|
<< minimumSize.width() << ',' << minimumSize.height()
|
||||||
<< " max=" << maximumSize.width() << ',' << maximumSize.height()
|
<< " max=" << maximumSize.width() << ',' << maximumSize.height()
|
||||||
@ -1041,6 +1048,13 @@ void QWindowsGeometryHint::applyToMinMaxInfo(const QWindow *w,
|
|||||||
qCDebug(lcQpaWindows).nospace() << '<' << __FUNCTION__ << " out " << *mmi;
|
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)
|
bool QWindowsGeometryHint::positionIncludesFrame(const QWindow *w)
|
||||||
{
|
{
|
||||||
return qt_window_private(const_cast<QWindow *>(w))->positionPolicy
|
return qt_window_private(const_cast<QWindow *>(w))->positionPolicy
|
||||||
@ -1226,11 +1240,12 @@ void QWindowsForeignWindow::setVisible(bool visible)
|
|||||||
\ingroup qt-lighthouse-win
|
\ingroup qt-lighthouse-win
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QWindowCreationContext::QWindowCreationContext(const QWindow *w,
|
QWindowCreationContext::QWindowCreationContext(const QWindow *w, const QScreen *s,
|
||||||
const QRect &geometryIn, const QRect &geometry,
|
const QRect &geometryIn, const QRect &geometry,
|
||||||
const QMargins &cm,
|
const QMargins &cm,
|
||||||
DWORD style, DWORD exStyle) :
|
DWORD style, DWORD exStyle) :
|
||||||
window(w),
|
window(w),
|
||||||
|
screen(s),
|
||||||
requestedGeometryIn(geometryIn),
|
requestedGeometryIn(geometryIn),
|
||||||
requestedGeometry(geometry),
|
requestedGeometry(geometry),
|
||||||
obtainedPos(geometryIn.topLeft()),
|
obtainedPos(geometryIn.topLeft()),
|
||||||
@ -1270,7 +1285,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
|
|||||||
|
|
||||||
void QWindowCreationContext::applyToMinMaxInfo(MINMAXINFO *mmi) const
|
void QWindowCreationContext::applyToMinMaxInfo(MINMAXINFO *mmi) const
|
||||||
{
|
{
|
||||||
QWindowsGeometryHint::applyToMinMaxInfo(window, margins + customMargins, mmi);
|
QWindowsGeometryHint::applyToMinMaxInfo(window, screen, margins + customMargins, mmi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -66,9 +66,12 @@ struct QWindowsGeometryHint
|
|||||||
static QMargins frame(const QWindow *w, const QRect &geometry,
|
static QMargins frame(const QWindow *w, const QRect &geometry,
|
||||||
DWORD style, DWORD exStyle);
|
DWORD style, DWORD exStyle);
|
||||||
static bool handleCalculateSize(const QMargins &customMargins, const MSG &msg, LRESULT *result);
|
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,
|
static void applyToMinMaxInfo(const QWindow *w, const QMargins &margins,
|
||||||
MINMAXINFO *mmi);
|
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);
|
QSize *minimumSize, QSize *maximumSize);
|
||||||
static inline QPoint mapToGlobal(HWND hwnd, const QPoint &);
|
static inline QPoint mapToGlobal(HWND hwnd, const QPoint &);
|
||||||
static inline QPoint mapToGlobal(const QWindow *w, const QPoint &);
|
static inline QPoint mapToGlobal(const QWindow *w, const QPoint &);
|
||||||
@ -80,13 +83,16 @@ struct QWindowsGeometryHint
|
|||||||
|
|
||||||
struct QWindowCreationContext
|
struct QWindowCreationContext
|
||||||
{
|
{
|
||||||
explicit QWindowCreationContext(const QWindow *w,
|
explicit QWindowCreationContext(const QWindow *w, const QScreen *s,
|
||||||
const QRect &geometryIn, const QRect &geometry,
|
const QRect &geometryIn, const QRect &geometry,
|
||||||
const QMargins &customMargins,
|
const QMargins &customMargins,
|
||||||
DWORD style, DWORD exStyle);
|
DWORD style, DWORD exStyle);
|
||||||
void applyToMinMaxInfo(MINMAXINFO *mmi) const;
|
void applyToMinMaxInfo(MINMAXINFO *mmi) const;
|
||||||
|
|
||||||
const QWindow *window;
|
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 requestedGeometryIn; // QWindow scaled
|
||||||
QRect requestedGeometry; // after QPlatformWindow::initialGeometry()
|
QRect requestedGeometry; // after QPlatformWindow::initialGeometry()
|
||||||
QPoint obtainedPos;
|
QPoint obtainedPos;
|
||||||
|
Loading…
Reference in New Issue
Block a user