summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowswindow.cpp
diff options
context:
space:
mode:
authorYuhang Zhao <2546789017@qq.com>2021-12-04 20:19:03 +0800
committerYuhang Zhao <2546789017@qq.com>2022-03-01 09:11:51 +0800
commit770ea68588f954b8465276908bdfeeb6bcf550e8 (patch)
treec85d254ec5bfda2867d8fef0b187f5e40415bb88 /src/plugins/platforms/windows/qwindowswindow.cpp
parent9c947c131d05d075f29fcfef6b0f36e38b30567b (diff)
Windows QPA: Use less magic number
The correct calculation of the invisible frame margin and the window border width (they are the same thing actually) is the thickness of the size frame plus the thickness of the padded border. When DPI is 96, both of them is 4px and thus the invisible frame margin and window border width is 8px. So previously the empirical magic number can work normally is because the error is very small. It's not a big thing because even on a high DPI screen the error is still very small. For example, on my 4K monitor with 200% scaling, the error is only 2px, human eyes almost can't find the visual difference. But since we now know how to calculate these values correctly, let's use the correct calculation instead. The magic numbers and empirical expressions just make people confused. Pick-to: 6.3 6.2 Change-Id: Ieda4796231935f2ad1b6f28e4aa4af5b5bce2256 Reviewed-by: André de la Rocha <andre.rocha@qt.io>
Diffstat (limited to 'src/plugins/platforms/windows/qwindowswindow.cpp')
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp40
1 files changed, 21 insertions, 19 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index e3ded434f4..1594a4057a 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -552,10 +552,18 @@ static inline void updateGLWindowSettings(const QWindow *w, HWND hwnd, Qt::Windo
setWindowOpacity(hwnd, flags, hasAlpha, isAccelerated, opacity);
}
+[[nodiscard]] static inline int getResizeBorderThickness(const UINT dpi)
+{
+ // The width of the padded border will always be 0 if DWM composition is
+ // disabled, but since it will always be enabled and can't be programtically
+ // disabled from Windows 8, we are safe to go.
+ return GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
+ + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
+}
+
/*!
Calculates the dimensions of the invisible borders within the
- window frames in Windows 10, using an empirical expression that
- reproduces the measured values for standard DPI settings.
+ window frames which only exist on Windows 10 and onwards.
*/
static QMargins invisibleMargins(QPoint screenPoint)
@@ -565,14 +573,20 @@ static QMargins invisibleMargins(QPoint screenPoint)
UINT dpiX;
UINT dpiY;
if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
- const qreal sc = (dpiX - 96) / 96.0;
- const int gap = 7 + qRound(5*sc) - int(sc);
+ const int gap = getResizeBorderThickness(dpiX);
return QMargins(gap, 0, gap, gap);
}
}
return QMargins();
}
+[[nodiscard]] static inline QMargins invisibleMargins(const HWND hwnd)
+{
+ const UINT dpi = GetDpiForWindow(hwnd);
+ const int gap = getResizeBorderThickness(dpi);
+ return QMargins(gap, 0, gap, gap);
+}
+
/*!
\class WindowCreationData
\brief Window creation code.
@@ -2675,7 +2689,7 @@ QMargins QWindowsWindow::frameMargins() const
{
QMargins result = fullFrameMargins();
if (isTopLevel() && m_data.hasFrame)
- result -= invisibleMargins(geometry().topLeft());
+ result -= invisibleMargins(m_data.hwnd);
return result;
}
@@ -2875,13 +2889,6 @@ void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled)
}
}
-static int getBorderWidth(const QPlatformScreen *screen)
-{
- NONCLIENTMETRICS ncm;
- QWindowsContext::nonClientMetricsForScreen(&ncm, screen);
- return ncm.iBorderWidth + ncm.iPaddedBorderWidth + 2;
-}
-
void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
{
QWindowsGeometryHint::applyToMinMaxInfo(window(), fullFrameMargins(), mmi);
@@ -2903,7 +2910,7 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
mmi->ptMaxPosition.x = availablePositionDiff.x();
mmi->ptMaxPosition.y = availablePositionDiff.y();
if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) {
- const int borderWidth = getBorderWidth(currentScreen);
+ const int borderWidth = invisibleMargins(m_data.hwnd).left();
mmi->ptMaxSize.x += borderWidth * 2;
mmi->ptMaxSize.y += borderWidth * 2;
mmi->ptMaxTrackSize = mmi->ptMaxSize;
@@ -2944,12 +2951,7 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re
return true;
}
if (localPos.y() < 0) {
- // We want to return HTCAPTION/true only over the outer sizing frame, not the entire title bar,
- // otherwise the title bar buttons (close, etc.) become unresponsive on Windows 7 (QTBUG-78262).
- // However, neither frameMargins() nor GetSystemMetrics(SM_CYSIZEFRAME), etc., give the correct
- // sizing frame height in all Windows versions/scales. This empirical constant seems to work, though.
- const int sizingHeight = 9;
- const int topResizeBarPos = sizingHeight - frameMargins().top();
+ const int topResizeBarPos = invisibleMargins(m_data.hwnd).left() - frameMargins().top();
if (localPos.y() < topResizeBarPos) {
*result = HTCAPTION; // Extend caption over top resize bar, let's user move the window.
return true;