Windows: Fix coordinate offset when positioning the taskbar on the left.

For windows that do not have WS_EX_TOOLWINDOW set, the WINDOWPLACEMENT
API uses workspace/available aera coordinates. Introduce a helper
function to return the offset and use that.

Task-number: QTBUG-43872
Change-Id: I329c640f180524699b45b855b4583f447c4a0987
Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
bb10
Friedemann Kleint 2015-01-19 15:00:05 +01:00
parent 8c5b3c6d91
commit 0b62cd8da7
4 changed files with 46 additions and 8 deletions

View File

@ -497,4 +497,13 @@ bool QWindowsScreenManager::handleScreenChanges()
return true;
}
const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const
{
foreach (QWindowsScreen *scr, m_screens) {
if (scr->geometryDp().contains(p))
return scr;
}
return Q_NULLPTR;
}
QT_END_NAMESPACE

View File

@ -137,6 +137,8 @@ public:
bool handleDisplayChange(WPARAM wParam, LPARAM lParam);
const WindowsScreenList &screens() const { return m_screens; }
const QWindowsScreen *screenAtDp(const QPoint &p) const;
private:
void removeScreen(int index);

View File

@ -169,6 +169,25 @@ QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p)
}
#endif // !Q_OS_WINCE
// QTBUG-43872, for windows that do not have WS_EX_TOOLWINDOW set, WINDOWPLACEMENT
// is in workspace/available area coordinates.
static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point)
{
#ifndef Q_OS_WINCE
if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)
return QPoint(0, 0);
const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager();
const QWindowsScreen *screen = screenManager.screens().size() == 1
? screenManager.screens().first() : screenManager.screenAtDp(point);
if (screen)
return screen->availableGeometryDp().topLeft() - screen->geometryDp().topLeft();
#else
Q_UNUSED(hwnd)
Q_UNUSED(point)
#endif
return QPoint(0, 0);
}
// Return the frame geometry relative to the parent
// if there is one.
static inline QRect frameGeometry(HWND hwnd, bool topLevel)
@ -179,8 +198,10 @@ static inline QRect frameGeometry(HWND hwnd, bool topLevel)
WINDOWPLACEMENT windowPlacement;
windowPlacement.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hwnd, &windowPlacement);
if (windowPlacement.showCmd == SW_SHOWMINIMIZED)
return qrectFromRECT(windowPlacement.rcNormalPosition);
if (windowPlacement.showCmd == SW_SHOWMINIMIZED) {
const QRect result = qrectFromRECT(windowPlacement.rcNormalPosition);
return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
}
}
#endif // !Q_OS_WINCE
GetWindowRect(hwnd, &rect); // Screen coordinates.
@ -1297,8 +1318,10 @@ static QRect normalFrameGeometry(HWND hwnd)
#ifndef Q_OS_WINCE
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(hwnd, &wp))
return qrectFromRECT(wp.rcNormalPosition);
if (GetWindowPlacement(hwnd, &wp)) {
const QRect result = qrectFromRECT(wp.rcNormalPosition);
return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
}
#else
Q_UNUSED(hwnd)
#endif
@ -1427,7 +1450,8 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const
// 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.rcNormalPosition =
RECTfromQRect(frameGeometry.translated(-windowPlacementOffset(m_data.hwnd, frameGeometry.topLeft())));
windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE;
result = SetWindowPlacement(m_data.hwnd, &windowPlacement);
} else

View File

@ -4696,8 +4696,9 @@ void tst_QWidget::setWindowGeometry()
void tst_QWidget::setGeometry_win()
{
QWidget widget;
setFrameless(&widget);
widget.setGeometry(0, 600, 100,100);
widget.setGeometry(QRect(m_availableTopLeft + QPoint(0, 600), QSize(100, 100)));
widget.show();
widget.setWindowState(widget.windowState() | Qt::WindowMaximized);
QRect geom = widget.normalGeometry();
@ -4707,8 +4708,10 @@ void tst_QWidget::setGeometry_win()
widget.show();
RECT rt;
::GetWindowRect(winHandleOf(&widget), &rt);
QVERIFY2(rt.left <= 0, msgComparisonFailed(int(rt.left), "<=", 0));
QVERIFY2(rt.top <= 0, msgComparisonFailed(int(rt.top), "<=", 0));
QVERIFY2(rt.left <= m_availableTopLeft.x(),
msgComparisonFailed(int(rt.left), "<=", m_availableTopLeft.x()));
QVERIFY2(rt.top <= m_availableTopLeft.y(),
msgComparisonFailed(int(rt.top), "<=", m_availableTopLeft.y()));
}
#endif // defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)