macOS: Respect QWindow frame positioning on first show
When the QCocoaWindow is created it picks up the QWindow geometry, and applies that to the NSWindow it creates. But since we haven't created an NSWindow yet for the first step, our logic to adjust the window geometry when the positionPolicy is WindowFrameInclusive is a noop. As a result the NSWindow gets a client geometry corresponding to what the user requested as the frame geometry. To fix this we hook into [QNSWindow setContentView:], where we apply QWindow properties to the NSWindow after creation. The tst_QWindow::positioning test has been split out into a separate framePositioning test. Pick-to: 6.7 6.5 Change-Id: I85fe6ad10aee8346202de3d55d6b2cd89915c5df Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> (cherry picked from commit 31ec108dd08d6381a15e49b6fbec9337705c3b2a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
8fc29f208b
commit
f31e7385c1
@ -225,6 +225,16 @@ NSWindow<QNSWindowProtocol> *qnswindow_cast(NSWindow *window)
|
||||
m_platformWindow->setWindowFilePath(window->filePath()); // Also sets window icon
|
||||
m_platformWindow->setWindowState(window->windowState());
|
||||
m_platformWindow->setOpacity(window->opacity());
|
||||
|
||||
// At the time of creation the QNSWindow is given a geometry based
|
||||
// on the client geometry of the QWindow. But at that point we don't
|
||||
// know anything about the size of the NSWindow frame, which means
|
||||
// that the logic in QCocoaWindow::setGeometry for adjusting the
|
||||
// client geometry based on the QWindow's positionPolicy is a noop.
|
||||
// Now that we have a NSWindow to read the frame from we re-apply
|
||||
// the QWindow geometry, which will move the NSWindow if needed.
|
||||
m_platformWindow->setGeometry(window->geometry());
|
||||
|
||||
m_platformWindow->setVisible(window->isVisible());
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,8 @@ private slots:
|
||||
void mapGlobal();
|
||||
void positioning_data();
|
||||
void positioning();
|
||||
void framePositioning();
|
||||
void framePositioning_data();
|
||||
void positioningDuringMinimized();
|
||||
void childWindowPositioning_data();
|
||||
void childWindowPositioning();
|
||||
@ -607,39 +609,64 @@ void tst_QWindow::positioning()
|
||||
QTRY_COMPARE(originalPos, window.position());
|
||||
QTRY_COMPARE(originalFramePos, window.framePosition());
|
||||
QTRY_COMPARE(originalMargins, window.frameMargins());
|
||||
}
|
||||
|
||||
// if our positioning is actually fully respected by the window manager
|
||||
// test whether it correctly handles frame positioning as well
|
||||
if (originalPos == geometry.topLeft() && (originalMargins.top() != 0 || originalMargins.left() != 0)) {
|
||||
const QScreen *screen = window.screen();
|
||||
const QRect availableGeometry = screen->availableGeometry();
|
||||
const QPoint framePos = availableGeometry.center();
|
||||
void tst_QWindow::framePositioning_data()
|
||||
{
|
||||
QTest::addColumn<bool>("showBeforePositioning");
|
||||
|
||||
window.reset();
|
||||
const QPoint oldFramePos = window.framePosition();
|
||||
window.setFramePosition(framePos);
|
||||
QTest::newRow("before show") << false;
|
||||
QTest::newRow("after show") << true;
|
||||
}
|
||||
|
||||
QTRY_VERIFY(window.received(QEvent::Move));
|
||||
const int fuzz = int(QHighDpiScaling::factor(&window));
|
||||
if (!qFuzzyCompareWindowPosition(window.framePosition(), framePos, fuzz)) {
|
||||
qDebug() << "About to fail auto-test. Here is some additional information:";
|
||||
qDebug() << "window.framePosition() == " << window.framePosition();
|
||||
qDebug() << "old frame position == " << oldFramePos;
|
||||
qDebug() << "We received " << window.received(QEvent::Move) << " move events";
|
||||
qDebug() << "frame positions after each move event:" << window.m_framePositionsOnMove;
|
||||
}
|
||||
QTRY_VERIFY2(qFuzzyCompareWindowPosition(window.framePosition(), framePos, fuzz),
|
||||
qPrintable(msgPointMismatch(window.framePosition(), framePos)));
|
||||
void tst_QWindow::framePositioning()
|
||||
{
|
||||
QFETCH(bool, showBeforePositioning);
|
||||
|
||||
Window window;
|
||||
const QScreen *screen = window.screen();
|
||||
const QRect availableGeometry = screen->availableGeometry();
|
||||
const QPoint screenCenter = availableGeometry.center();
|
||||
|
||||
const QPoint oldFramePos = window.framePosition();
|
||||
QMargins originalMargins;
|
||||
|
||||
if (showBeforePositioning) {
|
||||
window.showNormal();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
||||
originalMargins = window.frameMargins();
|
||||
window.setFramePosition(screenCenter);
|
||||
} else {
|
||||
window.setFramePosition(screenCenter);
|
||||
window.showNormal();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
||||
}
|
||||
|
||||
QTRY_VERIFY(window.received(QEvent::Move));
|
||||
const int fuzz = int(QHighDpiScaling::factor(&window));
|
||||
if (!qFuzzyCompareWindowPosition(window.framePosition(), screenCenter, fuzz)) {
|
||||
qDebug() << "About to fail auto-test. Here is some additional information:";
|
||||
qDebug() << "window.framePosition() == " << window.framePosition();
|
||||
qDebug() << "old frame position == " << oldFramePos;
|
||||
qDebug() << "We received " << window.received(QEvent::Move) << " move events";
|
||||
qDebug() << "frame positions after each move event:" << window.m_framePositionsOnMove;
|
||||
}
|
||||
QTRY_VERIFY2(qFuzzyCompareWindowPosition(window.framePosition(), screenCenter, fuzz),
|
||||
qPrintable(msgPointMismatch(window.framePosition(), screenCenter)));
|
||||
|
||||
if (showBeforePositioning) {
|
||||
// Repositioning should not affect existing margins
|
||||
QTRY_COMPARE(originalMargins, window.frameMargins());
|
||||
QCOMPARE(window.position(), window.framePosition() + QPoint(originalMargins.left(), originalMargins.top()));
|
||||
|
||||
// and back to regular positioning
|
||||
|
||||
window.reset();
|
||||
window.setPosition(originalPos);
|
||||
QTRY_VERIFY(window.received(QEvent::Move));
|
||||
QTRY_COMPARE(originalPos, window.position());
|
||||
}
|
||||
|
||||
// Check that regular positioning still works
|
||||
|
||||
const QPoint screenCenterAdjusted = screenCenter + QPoint(50, 50);
|
||||
window.reset();
|
||||
window.setPosition(screenCenterAdjusted);
|
||||
QTRY_VERIFY(window.received(QEvent::Move));
|
||||
QTRY_COMPARE(screenCenterAdjusted, window.position());
|
||||
}
|
||||
|
||||
void tst_QWindow::positioningDuringMinimized()
|
||||
|
Loading…
x
Reference in New Issue
Block a user