Windows: Restore window geometry after normal->maximized->fullscreen->normal.
- Do not save geometry when going from maximized->fullscreen - Use SW_SHOWNA instead SW_SHOWNOACTIVATE as otherwise the maximized geometry is restored. - Add a test for Windows. Task-number: QTBUG-49709 Change-Id: Ic81e7398ee90d499a50b02192a45cb09276a2105 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
This commit is contained in:
parent
ac5c2aaf35
commit
e3288f246b
@ -1720,7 +1720,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
|
||||
if (!m_savedStyle) {
|
||||
m_savedStyle = style();
|
||||
#ifndef Q_OS_WINCE
|
||||
if (oldState == Qt::WindowMinimized) {
|
||||
if (oldState == Qt::WindowMinimized || oldState == Qt::WindowMaximized) {
|
||||
const QRect nf = normalFrameGeometry(m_data.hwnd);
|
||||
if (nf.isValid())
|
||||
m_savedFrameGeometry = nf;
|
||||
@ -1771,7 +1771,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
|
||||
// preserve maximized state
|
||||
if (visible) {
|
||||
setFlag(WithinMaximize);
|
||||
ShowWindow(m_data.hwnd, (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
|
||||
ShowWindow(m_data.hwnd, (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNA);
|
||||
clearFlag(WithinMaximize);
|
||||
}
|
||||
m_savedStyle = 0;
|
||||
|
@ -95,6 +95,8 @@ private slots:
|
||||
void windowsTransientChildren();
|
||||
void requestUpdate();
|
||||
void initTestCase();
|
||||
void stateChange_data();
|
||||
void stateChange();
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
@ -272,6 +274,18 @@ static inline bool qFuzzyCompareWindowPosition(const QPoint &p1, const QPoint p2
|
||||
return (p1 - p2).manhattanLength() <= fuzz;
|
||||
}
|
||||
|
||||
static inline bool qFuzzyCompareWindowSize(const QSize &s1, const QSize &s2, int fuzz)
|
||||
{
|
||||
const int manhattanLength = qAbs(s1.width() - s2.width()) + qAbs(s1.height() - s2.height());
|
||||
return manhattanLength <= fuzz;
|
||||
}
|
||||
|
||||
static inline bool qFuzzyCompareWindowGeometry(const QRect &r1, const QRect &r2, int fuzz)
|
||||
{
|
||||
return qFuzzyCompareWindowPosition(r1.topLeft(), r2.topLeft(), fuzz)
|
||||
&& qFuzzyCompareWindowSize(r1.size(), r2.size(), fuzz);
|
||||
}
|
||||
|
||||
static QString msgPointMismatch(const QPoint &p1, const QPoint p2)
|
||||
{
|
||||
QString result;
|
||||
@ -279,6 +293,13 @@ static QString msgPointMismatch(const QPoint &p1, const QPoint p2)
|
||||
return result;
|
||||
}
|
||||
|
||||
static QString msgRectMismatch(const QRect &r1, const QRect &r2)
|
||||
{
|
||||
QString result;
|
||||
QDebug(&result) << r1 << "!=" << r2;
|
||||
return result;
|
||||
}
|
||||
|
||||
void tst_QWindow::positioning()
|
||||
{
|
||||
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(
|
||||
@ -394,6 +415,52 @@ void tst_QWindow::positioningDuringMinimized()
|
||||
QTRY_COMPARE(window.geometry(), newGeometry);
|
||||
}
|
||||
|
||||
// QTBUG-49709: Verify that the normal geometry is correctly restored
|
||||
// when executing a sequence of window state changes. So far, Windows
|
||||
// only where state changes have immediate effect.
|
||||
|
||||
typedef QList<Qt::WindowState> WindowStateList;
|
||||
|
||||
Q_DECLARE_METATYPE(WindowStateList)
|
||||
|
||||
void tst_QWindow::stateChange_data()
|
||||
{
|
||||
QTest::addColumn<WindowStateList>("stateSequence");
|
||||
|
||||
QTest::newRow("normal->min->normal") <<
|
||||
(WindowStateList() << Qt::WindowMinimized << Qt::WindowNoState);
|
||||
QTest::newRow("normal->maximized->normal") <<
|
||||
(WindowStateList() << Qt::WindowMaximized << Qt::WindowNoState);
|
||||
QTest::newRow("normal->fullscreen->normal") <<
|
||||
(WindowStateList() << Qt::WindowFullScreen << Qt::WindowNoState);
|
||||
QTest::newRow("normal->maximized->fullscreen->normal") <<
|
||||
(WindowStateList() << Qt::WindowMaximized << Qt::WindowFullScreen << Qt::WindowNoState);
|
||||
}
|
||||
|
||||
void tst_QWindow::stateChange()
|
||||
{
|
||||
QFETCH(WindowStateList, stateSequence);
|
||||
|
||||
if (QGuiApplication::platformName().compare(QLatin1String("windows"), Qt::CaseInsensitive))
|
||||
QSKIP("Windows-only test");
|
||||
|
||||
Window window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1Char(' ') + QLatin1String(QTest::currentDataTag()));
|
||||
const QRect normalGeometry(m_availableTopLeft + QPoint(40, 40), m_testWindowSize);
|
||||
window.setGeometry(normalGeometry);
|
||||
// explicitly use non-fullscreen show. show() can be fullscreen on some platforms
|
||||
window.showNormal();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
||||
foreach (Qt::WindowState state, stateSequence) {
|
||||
window.setWindowState(state);
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
const QRect geometry = window.geometry();
|
||||
const int fuzz = int(QHighDpiScaling::factor(&window));
|
||||
QVERIFY2(qFuzzyCompareWindowGeometry(geometry, normalGeometry, fuzz),
|
||||
qPrintable(msgRectMismatch(geometry, normalGeometry)));
|
||||
}
|
||||
|
||||
class PlatformWindowFilter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
Loading…
x
Reference in New Issue
Block a user