Windows QPA: Change handling of maximised frame/title-less windows

So far, the framele/tite-less window maximising has been done by
adjusting the MINMAXINFO to prevent them from covering the taskbar.
It does not work when moving the windows from one screen to another
using keyboard shortcuts, since the MINMAXINFO is that of the old
monitor. This moves the adjustment to the WM_SIZE message that occurs
after the window has been resized.

Pick-to: 6.5 6.4 6.2
Change-Id: I0d36fe5d2e8eaa0739414835b8d99a0b2ed44cf6
Reviewed-by: Yuhang Zhao <yuhangzhao@deepin.org>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
This commit is contained in:
Timothée Keller 2023-03-13 17:21:13 +01:00
parent 3f40a8b5b1
commit eafe577041
3 changed files with 36 additions and 33 deletions

View File

@ -1191,7 +1191,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
platformWindow->handleMoved();
return true;
case QtWindows::ResizeEvent:
platformWindow->handleResized(static_cast<int>(wParam));
platformWindow->handleResized(static_cast<int>(wParam), lParam);
return true;
case QtWindows::QuerySizeHints:
platformWindow->getSizeHints(reinterpret_cast<MINMAXINFO *>(lParam));

View File

@ -2138,8 +2138,41 @@ void QWindowsWindow::handleMoved()
handleGeometryChange();
}
void QWindowsWindow::handleResized(int wParam)
void QWindowsWindow::handleResized(int wParam, LPARAM lParam)
{
/* Prevents borderless windows from covering the taskbar when maximized. */
if ((m_data.flags.testFlag(Qt::FramelessWindowHint)
|| (m_data.flags.testFlag(Qt::CustomizeWindowHint) && !m_data.flags.testFlag(Qt::WindowTitleHint)))
&& IsZoomed(m_data.hwnd)) {
const int resizedWidth = LOWORD(lParam);
const int resizedHeight = HIWORD(lParam);
const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTOPRIMARY);
MONITORINFO monitorInfo = {};
monitorInfo.cbSize = sizeof(MONITORINFO);
GetMonitorInfoW(monitor, &monitorInfo);
int correctLeft = monitorInfo.rcMonitor.left;
int correctTop = monitorInfo.rcMonitor.top;
int correctWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
int correctHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) {
const int borderWidth = invisibleMargins(m_data.hwnd).left();
correctLeft -= borderWidth;
correctTop -= borderWidth;
correctWidth += borderWidth * 2;
correctHeight += borderWidth * 2;
}
if (resizedWidth != correctWidth || resizedHeight != correctHeight) {
qCDebug(lcQpaWindow) << __FUNCTION__ << "correcting: " << resizedWidth << "x"
<< resizedHeight << " -> " << correctWidth << "x" << correctHeight;
SetWindowPos(m_data.hwnd, nullptr, correctLeft, correctTop, correctWidth, correctHeight,
SWP_NOZORDER | SWP_NOACTIVATE);
}
}
switch (wParam) {
case SIZE_MAXHIDE: // Some other window affected.
case SIZE_MAXSHOW:
@ -2953,36 +2986,6 @@ void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled)
void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
{
QWindowsGeometryHint::applyToMinMaxInfo(window(), fullFrameMargins(), mmi);
// This block fixes QTBUG-8361, QTBUG-4362: Frameless/title-less windows shouldn't cover the
// taskbar when maximized
if (m_data.flags.testFlag(Qt::FramelessWindowHint)
|| (m_data.flags.testFlag(Qt::CustomizeWindowHint) && !m_data.flags.testFlag(Qt::WindowTitleHint))) {
if (QPlatformScreen *currentScreen = screen()) {
const QRect geometry = currentScreen->geometry();
const QRect availableGeometry = currentScreen->availableGeometry();
mmi->ptMaxSize.y = availableGeometry.height();
// Width, because you can have the taskbar on the sides too.
mmi->ptMaxSize.x = availableGeometry.width();
// If you have the taskbar on top, or on the left you don't want it at (0,0):
QPoint availablePositionDiff = availableGeometry.topLeft() - geometry.topLeft();
mmi->ptMaxPosition.x = availablePositionDiff.x();
mmi->ptMaxPosition.y = availablePositionDiff.y();
if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) {
const int borderWidth = invisibleMargins(m_data.hwnd).left();
mmi->ptMaxSize.x += borderWidth * 2;
mmi->ptMaxSize.y += borderWidth * 2;
mmi->ptMaxTrackSize = mmi->ptMaxSize;
mmi->ptMaxPosition.x -= borderWidth;
mmi->ptMaxPosition.y -= borderWidth;
}
} else {
qWarning("screen() returned a null screen");
}
}
qCDebug(lcQpaWindow) << __FUNCTION__ << window() << *mmi;
}

View File

@ -281,7 +281,7 @@ public:
bool handleWmPaint(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
void handleMoved();
void handleResized(int wParam);
void handleResized(int wParam, LPARAM lParam);
void handleHidden();
void handleCompositionSettingsChanged();
void handleDpiScaledSize(WPARAM wParam, LPARAM lParam, LRESULT *result);