Windows: Fix setting of geometries in minimized state.

Use SetWindowPlacement() to set the normal position when applicable
as is done in Qt 4.

Task-number: QTBUG-39544
Change-Id: Ia158b968ea15361d9937619f07b56eb8a0312a13
Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
This commit is contained in:
Friedemann Kleint 2014-06-19 13:45:06 +02:00
parent 71c6fdf871
commit 40f5a4d5f8
2 changed files with 49 additions and 4 deletions

View File

@ -181,6 +181,14 @@ QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p)
static inline QRect frameGeometry(HWND hwnd, bool topLevel) static inline QRect frameGeometry(HWND hwnd, bool topLevel)
{ {
RECT rect = { 0, 0, 0, 0 }; RECT rect = { 0, 0, 0, 0 };
#ifndef Q_OS_WINCE
if (topLevel) {
WINDOWPLACEMENT windowPlacement;
GetWindowPlacement(hwnd, &windowPlacement);
if (windowPlacement.showCmd == SW_SHOWMINIMIZED)
return qrectFromRECT(windowPlacement.rcNormalPosition);
}
#endif // !Q_OS_WINCE
GetWindowRect(hwnd, &rect); // Screen coordinates. GetWindowRect(hwnd, &rect); // Screen coordinates.
const HWND parent = GetParent(hwnd); const HWND parent = GetParent(hwnd);
if (parent && !topLevel) { if (parent && !topLevel) {
@ -1424,15 +1432,29 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const
<< margins << " to " <<rect << margins << " to " <<rect
<< " new frame: " << frameGeometry; << " new frame: " << frameGeometry;
const bool rc = MoveWindow(m_data.hwnd, frameGeometry.x(), frameGeometry.y(), bool result = false;
frameGeometry.width(), frameGeometry.height(), true); #ifndef Q_OS_WINCE
WINDOWPLACEMENT windowPlacement;
GetWindowPlacement(m_data.hwnd, &windowPlacement);
// If the window is hidden and in maximized state or minimized, instead of moving the
// window, set the normal position of the window.
if ((windowPlacement.showCmd == SW_MAXIMIZE && !IsWindowVisible(m_data.hwnd))
|| windowPlacement.showCmd == SW_SHOWMINIMIZED) {
windowPlacement.rcNormalPosition = RECTfromQRect(frameGeometry);
windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE;
result = SetWindowPlacement(m_data.hwnd, &windowPlacement);
} else
#endif // !Q_OS_WINCE
{
result = MoveWindow(m_data.hwnd, frameGeometry.x(), frameGeometry.y(),
frameGeometry.width(), frameGeometry.height(), true);
}
qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window() qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window()
<< " \n resulting " << rc << geometry_sys(); << " \n resulting " << result << geometry_sys();
} }
QRect QWindowsWindow::frameGeometry_sys() const QRect QWindowsWindow::frameGeometry_sys() const
{ {
// Warning: Returns bogus values when minimized.
bool isRealTopLevel = window()->isTopLevel() && !m_data.embedded; bool isRealTopLevel = window()->isTopLevel() && !m_data.embedded;
return frameGeometry(m_data.hwnd, isRealTopLevel); return frameGeometry(m_data.hwnd, isRealTopLevel);
} }

View File

@ -67,6 +67,7 @@ private slots:
void mapGlobal(); void mapGlobal();
void positioning_data(); void positioning_data();
void positioning(); void positioning();
void positioningDuringMinimized();
void isExposed(); void isExposed();
void isActive(); void isActive();
void testInputEvents(); void testInputEvents();
@ -306,6 +307,28 @@ void tst_QWindow::positioning()
} }
} }
void tst_QWindow::positioningDuringMinimized()
{
// QTBUG-39544, setting a geometry in minimized state should work as well.
if (QGuiApplication::platformName().compare("windows", Qt::CaseInsensitive))
QSKIP("Not supported on this platform");
Window window;
window.setTitle(QStringLiteral("positioningDuringMinimized"));
const QRect initialGeometry(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(100, 100),
QSize(200, 200));
window.setGeometry(initialGeometry);
window.showNormal();
QVERIFY(QTest::qWaitForWindowExposed(&window));
QCOMPARE(window.geometry(), initialGeometry);
window.setWindowState(Qt::WindowMinimized);
QCOMPARE(window.geometry(), initialGeometry);
const QRect newGeometry(initialGeometry.topLeft() + QPoint(50, 50), initialGeometry.size() + QSize(50, 50));
window.setGeometry(newGeometry);
QTRY_COMPARE(window.geometry(), newGeometry);
window.setWindowState(Qt::WindowNoState);
QTRY_COMPARE(window.geometry(), newGeometry);
}
void tst_QWindow::isExposed() void tst_QWindow::isExposed()
{ {
QRect geometry(80, 80, 40, 40); QRect geometry(80, 80, 40, 40);