From 136b865853623acfb5167ec5e9fb1d6d36ee5458 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Sat, 9 May 2020 12:58:01 +0800 Subject: [PATCH] Minor improvements. 1. Use const more. 2. Add some missing ResolveWin32APIs() call 3. Move updateQtFrame to WinNativeEventFilter Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- main_windows.cpp | 34 +------ winnativeeventfilter.cpp | 189 ++++++++++++++++++++++++++------------- winnativeeventfilter.h | 45 ++++++---- 3 files changed, 158 insertions(+), 110 deletions(-) diff --git a/main_windows.cpp b/main_windows.cpp index 26063fa..d9f93b6 100644 --- a/main_windows.cpp +++ b/main_windows.cpp @@ -2,43 +2,17 @@ #include #include #include -#include #include #ifdef QT_QUICK_LIB #include #include #include -#else -#include #endif #include #include -#include -Q_DECLARE_METATYPE(QMargins) - -static const int m_defaultTitleBarHeight = 30; static const int m_defaultButtonWidth = 45; -static void updateQtFrame(QWindow *const window, const int titleBarHeight) { - if (window && (titleBarHeight > 0)) { - // Reduce top frame to zero since we paint it ourselves. Use - // device pixel to avoid rounding errors. - const QMargins margins = {0, -titleBarHeight, 0, 0}; - const QVariant marginsVar = QVariant::fromValue(margins); - // The dynamic property takes effect when creating the platform - // window. - window->setProperty("_q_windowsCustomMargins", marginsVar); - // If a platform window exists, change via native interface. - QPlatformWindow *platformWindow = window->handle(); - if (platformWindow) { - QGuiApplication::platformNativeInterface()->setWindowProperty( - platformWindow, QString::fromUtf8("WindowsCustomMargins"), - marginsVar); - } - } -} - #ifdef QT_QUICK_LIB class MyQuickView : public QQuickView { Q_OBJECT @@ -139,10 +113,6 @@ int main(int argc, char *argv[]) { data_widget->ignoreObjects << minimizeButton << maximizeButton << closeButton; } - const int tbh_widget = WinNativeEventFilter::getSystemMetric( - hWnd_widget, WinNativeEventFilter::SystemMetric::TitleBarHeight, false); - updateQtFrame(widget.windowHandle(), - (tbh_widget > 0 ? tbh_widget : m_defaultTitleBarHeight)); widget.resize(800, 600); WinNativeEventFilter::moveWindowToDesktopCenter(hWnd_widget); widget.show(); @@ -151,9 +121,8 @@ int main(int argc, char *argv[]) { // Qt Quick example: MyQuickView view; const auto hWnd_qml = reinterpret_cast(view.winId()); - const int tbh_qml_sys = WinNativeEventFilter::getSystemMetric( + const int tbh_qml = WinNativeEventFilter::getSystemMetric( hWnd_qml, WinNativeEventFilter::SystemMetric::TitleBarHeight, false); - const int tbh_qml = tbh_qml_sys > 0 ? tbh_qml_sys : m_defaultTitleBarHeight; view.rootContext()->setContextProperty(QString::fromUtf8("$TitleBarHeight"), tbh_qml); view.setSource(QUrl(QString::fromUtf8("qrc:///qml/main.qml"))); @@ -182,7 +151,6 @@ int main(int argc, char *argv[]) { QObject::connect(rootObject, SIGNAL(closeButtonClicked()), &view, SLOT(close())); WinNativeEventFilter::addFramelessWindow(hWnd_qml); - updateQtFrame(&view, tbh_qml); view.resize(800, 600); WinNativeEventFilter::moveWindowToDesktopCenter(hWnd_qml); view.show(); diff --git a/winnativeeventfilter.cpp b/winnativeeventfilter.cpp index 68efed1..a729343 100644 --- a/winnativeeventfilter.cpp +++ b/winnativeeventfilter.cpp @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include #if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) #include #else @@ -40,6 +43,8 @@ #endif #include +Q_DECLARE_METATYPE(QMargins) + namespace { // All the following enums, structs and function prototypes are copied from @@ -184,6 +189,9 @@ const UINT m_defaultDotsPerInch = USER_DEFAULT_SCREEN_DPI; const qreal m_defaultDevicePixelRatio = 1.0; +const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, + m_defaultTitleBarHeight = 30; + int m_borderWidth = -1, m_borderHeight = -1, m_titleBarHeight = -1; using HPAINTBUFFER = HANDLE; @@ -491,7 +499,7 @@ BOOL IsDwmCompositionEnabled() { return SUCCEEDED(m_lpDwmIsCompositionEnabled(&enabled)) && enabled; } -WINDOWINFO GetInfoForWindow(HWND handle) { +WINDOWINFO GetInfoForWindow(const HWND handle) { WINDOWINFO windowInfo; SecureZeroMemory(&windowInfo, sizeof(windowInfo)); windowInfo.cbSize = sizeof(windowInfo); @@ -501,7 +509,7 @@ WINDOWINFO GetInfoForWindow(HWND handle) { return windowInfo; } -MONITORINFO GetMonitorInfoForWindow(HWND handle) { +MONITORINFO GetMonitorInfoForWindow(const HWND handle) { MONITORINFO monitorInfo; SecureZeroMemory(&monitorInfo, sizeof(monitorInfo)); monitorInfo.cbSize = sizeof(monitorInfo); @@ -515,7 +523,7 @@ MONITORINFO GetMonitorInfoForWindow(HWND handle) { return monitorInfo; } -BOOL IsFullScreen(HWND handle) { +BOOL IsFullScreen(const HWND handle) { if (handle && m_lpIsWindow(handle)) { const WINDOWINFO windowInfo = GetInfoForWindow(handle); const MONITORINFO monitorInfo = GetMonitorInfoForWindow(handle); @@ -528,7 +536,7 @@ BOOL IsFullScreen(HWND handle) { return FALSE; } -BOOL IsTopLevel(HWND handle) { +BOOL IsTopLevel(const HWND handle) { if (handle && m_lpIsWindow(handle)) { if (m_lpGetWindowLongPtrW(handle, GWL_STYLE) & WS_CHILD) { return FALSE; @@ -542,8 +550,8 @@ BOOL IsTopLevel(HWND handle) { return FALSE; } -UINT GetDotsPerInchForWindow(HWND handle) { - const auto getScreenDpi = [](UINT defaultValue) -> UINT { +UINT GetDotsPerInchForWindow(const HWND handle) { + const auto getScreenDpi = [](const UINT defaultValue) -> UINT { #if 0 if (m_lpD2D1CreateFactory) { // Using Direct2D to get the screen DPI. @@ -607,9 +615,9 @@ UINT GetDotsPerInchForWindow(HWND handle) { return getScreenDpi(m_defaultDotsPerInch); } -qreal GetPreferedNumber(qreal num) { +qreal GetPreferedNumber(const qreal num) { qreal result = -1.0; - const auto getRoundedNumber = [](qreal in) -> qreal { + const auto getRoundedNumber = [](const qreal in) -> qreal { // If the given number is not very large, we assume it's a // device pixel ratio (DPR), otherwise we assume it's a DPI. if (in < m_defaultDotsPerInch) { @@ -660,7 +668,7 @@ qreal GetPreferedNumber(qreal num) { return result; } -qreal GetDevicePixelRatioForWindow(HWND handle) { +qreal GetDevicePixelRatioForWindow(const HWND handle) { qreal result = m_defaultDevicePixelRatio; if (handle && m_lpIsWindow(handle)) { result = static_cast(GetDotsPerInchForWindow(handle)) / @@ -669,7 +677,8 @@ qreal GetDevicePixelRatioForWindow(HWND handle) { return GetPreferedNumber(result); } -RECT GetFrameSizeForWindow(HWND handle, bool includingTitleBar = false) { +RECT GetFrameSizeForWindow(const HWND handle, + const bool includingTitleBar = false) { RECT rect = {0, 0, 0, 0}; if (handle && m_lpIsWindow(handle)) { const auto style = m_lpGetWindowLongPtrW(handle, GWL_STYLE); @@ -703,7 +712,7 @@ RECT GetFrameSizeForWindow(HWND handle, bool includingTitleBar = false) { return rect; } -void UpdateFrameMarginsForWindow(HWND handle) { +void UpdateFrameMarginsForWindow(const HWND handle) { if (handle && m_lpIsWindow(handle)) { MARGINS margins = {0, 0, 0, 0}; if (IsDwmCompositionEnabled()) { @@ -729,7 +738,7 @@ void UpdateFrameMarginsForWindow(HWND handle) { } } -int GetSystemMetricsForWindow(HWND handle, int index) { +int GetSystemMetricsForWindow(const HWND handle, const int index) { if (handle && m_lpIsWindow(handle)) { if (m_lpGetSystemMetricsForDpi) { return m_lpGetSystemMetricsForDpi( @@ -744,7 +753,7 @@ int GetSystemMetricsForWindow(HWND handle, int index) { return -1; } -void createUserData(HWND handle, +void createUserData(const HWND handle, const WinNativeEventFilter::WINDOWDATA *data = nullptr) { if (handle && m_lpIsWindow(handle)) { const auto userData = reinterpret_cast( @@ -804,26 +813,29 @@ QVector WinNativeEventFilter::framelessWindows() { return m_framelessWindows; } -void WinNativeEventFilter::setFramelessWindows(QVector windows) { +void WinNativeEventFilter::setFramelessWindows(const QVector &windows) { if (!windows.isEmpty() && (windows != m_framelessWindows)) { m_framelessWindows = windows; for (auto &&window : qAsConst(m_framelessWindows)) { createUserData(window); + updateQtFrame_internal(window); } install(); } } -void WinNativeEventFilter::addFramelessWindow(HWND window, +void WinNativeEventFilter::addFramelessWindow(const HWND window, const WINDOWDATA *data, - bool center, int x, int y, - int width, int height) { + const bool center, const int x, + const int y, const int width, + const int height) { ResolveWin32APIs(); if (window && m_lpIsWindow(window) && !m_framelessWindows.contains(window)) { m_framelessWindows.append(window); createUserData(window, data); install(); + updateQtFrame_internal(window); } if ((x > 0) && (y > 0) && (width > 0) && (height > 0)) { setWindowGeometry(window, x, y, width, height); @@ -833,7 +845,7 @@ void WinNativeEventFilter::addFramelessWindow(HWND window, } } -void WinNativeEventFilter::removeFramelessWindow(HWND window) { +void WinNativeEventFilter::removeFramelessWindow(const HWND window) { if (window && m_framelessWindows.contains(window)) { m_framelessWindows.removeAll(window); } @@ -1242,7 +1254,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, *result = HTTRANSPARENT; return true; } - const auto getHTResult = [](HWND _hWnd, LPARAM _lParam, + const auto getHTResult = [](const HWND _hWnd, const LPARAM _lParam, const WINDOW *_data) -> LRESULT { const auto isInSpecificAreas = [](const int x, const int y, const QVector &areas, @@ -1407,38 +1419,38 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, const MONITORINFO monitorInfo = GetMonitorInfoForWindow(msg->hwnd); const RECT rcWorkArea = monitorInfo.rcWork; const RECT rcMonitorArea = monitorInfo.rcMonitor; - auto &mmi = *reinterpret_cast(msg->lParam); + const auto mmi = reinterpret_cast(msg->lParam); if (isWin8OrGreator()) { // Works fine on Windows 8/8.1/10 - mmi.ptMaxPosition.x = + mmi->ptMaxPosition.x = qAbs(rcWorkArea.left - rcMonitorArea.left); - mmi.ptMaxPosition.y = qAbs(rcWorkArea.top - rcMonitorArea.top); + mmi->ptMaxPosition.y = qAbs(rcWorkArea.top - rcMonitorArea.top); } else { // ### FIXME: Buggy on Windows 7: // The origin of coordinates is the top left edge of the // monitor's work area. Why? It should be the top left edge of // the monitor's area. - mmi.ptMaxPosition.x = rcMonitorArea.left; - mmi.ptMaxPosition.y = rcMonitorArea.top; + mmi->ptMaxPosition.x = rcMonitorArea.left; + mmi->ptMaxPosition.y = rcMonitorArea.top; } if (data->windowData.maximumSize.isEmpty()) { - mmi.ptMaxSize.x = qAbs(rcWorkArea.right - rcWorkArea.left); - mmi.ptMaxSize.y = qAbs(rcWorkArea.bottom - rcWorkArea.top); + mmi->ptMaxSize.x = qAbs(rcWorkArea.right - rcWorkArea.left); + mmi->ptMaxSize.y = qAbs(rcWorkArea.bottom - rcWorkArea.top); } else { - mmi.ptMaxSize.x = + mmi->ptMaxSize.x = qRound(GetDevicePixelRatioForWindow(msg->hwnd) * data->windowData.maximumSize.width()); - mmi.ptMaxSize.y = + mmi->ptMaxSize.y = qRound(GetDevicePixelRatioForWindow(msg->hwnd) * data->windowData.maximumSize.height()); } - mmi.ptMaxTrackSize.x = mmi.ptMaxSize.x; - mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y; + mmi->ptMaxTrackSize.x = mmi->ptMaxSize.x; + mmi->ptMaxTrackSize.y = mmi->ptMaxSize.y; if (!data->windowData.minimumSize.isEmpty()) { - mmi.ptMinTrackSize.x = + mmi->ptMinTrackSize.x = qRound(GetDevicePixelRatioForWindow(msg->hwnd) * data->windowData.minimumSize.width()); - mmi.ptMinTrackSize.y = + mmi->ptMinTrackSize.y = qRound(GetDevicePixelRatioForWindow(msg->hwnd) * data->windowData.minimumSize.height()); } @@ -1497,7 +1509,8 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, return false; } -void WinNativeEventFilter::setWindowData(HWND window, const WINDOWDATA *data) { +void WinNativeEventFilter::setWindowData(const HWND window, + const WINDOWDATA *data) { ResolveWin32APIs(); if (window && m_lpIsWindow(window) && data) { createUserData(window, data); @@ -1505,27 +1518,30 @@ void WinNativeEventFilter::setWindowData(HWND window, const WINDOWDATA *data) { } WinNativeEventFilter::WINDOWDATA * -WinNativeEventFilter::windowData(HWND window) { +WinNativeEventFilter::windowData(const HWND window) { ResolveWin32APIs(); if (window && m_lpIsWindow(window)) { createUserData(window); - return &reinterpret_cast( - m_lpGetWindowLongPtrW(window, GWLP_USERDATA)) - ->windowData; + return &(reinterpret_cast( + m_lpGetWindowLongPtrW(window, GWLP_USERDATA)) + ->windowData); } return nullptr; } -void WinNativeEventFilter::setBorderWidth(int bw) { m_borderWidth = bw; } +void WinNativeEventFilter::setBorderWidth(const int bw) { m_borderWidth = bw; } -void WinNativeEventFilter::setBorderHeight(int bh) { m_borderHeight = bh; } +void WinNativeEventFilter::setBorderHeight(const int bh) { + m_borderHeight = bh; +} -void WinNativeEventFilter::setTitleBarHeight(int tbh) { +void WinNativeEventFilter::setTitleBarHeight(const int tbh) { m_titleBarHeight = tbh; } -void WinNativeEventFilter::updateWindow(HWND handle, bool triggerFrameChange, - bool redraw) { +void WinNativeEventFilter::updateWindow(const HWND handle, + const bool triggerFrameChange, + const bool redraw) { ResolveWin32APIs(); if (handle && m_lpIsWindow(handle)) { if (triggerFrameChange) { @@ -1540,8 +1556,9 @@ void WinNativeEventFilter::updateWindow(HWND handle, bool triggerFrameChange, } } -int WinNativeEventFilter::getSystemMetric(HWND handle, SystemMetric metric, - bool dpiAware) { +int WinNativeEventFilter::getSystemMetric(const HWND handle, + const SystemMetric metric, + const bool dpiAware) { ResolveWin32APIs(); const qreal dpr = dpiAware ? GetDevicePixelRatioForWindow(handle) : m_defaultDevicePixelRatio; @@ -1555,12 +1572,13 @@ int WinNativeEventFilter::getSystemMetric(HWND handle, SystemMetric metric, if (bw > 0) { return qRound(bw * dpr); } else { - const int result = m_lpGetSystemMetrics(SM_CXSIZEFRAME) + + const int result_nondpi = m_lpGetSystemMetrics(SM_CXSIZEFRAME) + m_lpGetSystemMetrics(SM_CXPADDEDBORDER); const int result_dpi = GetSystemMetricsForWindow(handle, SM_CXSIZEFRAME) + GetSystemMetricsForWindow(handle, SM_CXPADDEDBORDER); - return dpiAware ? result_dpi : result; + const int result = dpiAware ? result_dpi : result_nondpi; + return result > 0 ? result : qRound(m_defaultBorderWidth * dpr); } } case SystemMetric::BorderHeight: { @@ -1568,12 +1586,14 @@ int WinNativeEventFilter::getSystemMetric(HWND handle, SystemMetric metric, if (bh > 0) { return qRound(bh * dpr); } else { - const int result = m_lpGetSystemMetrics(SM_CYSIZEFRAME) + + const int result_nondpi = m_lpGetSystemMetrics(SM_CYSIZEFRAME) + m_lpGetSystemMetrics(SM_CXPADDEDBORDER); const int result_dpi = GetSystemMetricsForWindow(handle, SM_CYSIZEFRAME) + GetSystemMetricsForWindow(handle, SM_CXPADDEDBORDER); - return dpiAware ? result_dpi : result; + const int result = dpiAware ? result_dpi : result_nondpi; + return result > 0 ? result + : qRound(m_defaultBorderHeight * dpr); } } case SystemMetric::TitleBarHeight: { @@ -1581,40 +1601,43 @@ int WinNativeEventFilter::getSystemMetric(HWND handle, SystemMetric metric, if (tbh > 0) { return qRound(tbh * dpr); } else { - const int result = m_lpGetSystemMetrics(SM_CYCAPTION); + const int result_nondpi = m_lpGetSystemMetrics(SM_CYCAPTION); const int result_dpi = GetSystemMetricsForWindow(handle, SM_CYCAPTION); - return dpiAware ? result_dpi : result; + const int result = dpiAware ? result_dpi : result_nondpi; + return result > 0 ? result + : qRound(m_defaultTitleBarHeight * dpr); } } } } switch (metric) { - case SystemMetric::BorderWidth: { + case SystemMetric::BorderWidth: if (m_borderWidth > 0) { return qRound(m_borderWidth * dpr); + } else { + return qRound(m_defaultBorderWidth * dpr); } - break; - } - case SystemMetric::BorderHeight: { + case SystemMetric::BorderHeight: if (m_borderHeight > 0) { return qRound(m_borderHeight * dpr); + } else { + return qRound(m_defaultBorderHeight * dpr); } - break; - } - case SystemMetric::TitleBarHeight: { + case SystemMetric::TitleBarHeight: if (m_titleBarHeight > 0) { return qRound(m_titleBarHeight * dpr); + } else { + return qRound(m_defaultTitleBarHeight * dpr); } - break; - } } return -1; } -void WinNativeEventFilter::setWindowGeometry(HWND handle, const int x, +void WinNativeEventFilter::setWindowGeometry(const HWND handle, const int x, const int y, const int width, const int height) { + ResolveWin32APIs(); if (handle && m_lpIsWindow(handle) && (x > 0) && (y > 0) && (width > 0) && (height > 0)) { const qreal dpr = GetDevicePixelRatioForWindow(handle); @@ -1627,7 +1650,8 @@ void WinNativeEventFilter::setWindowGeometry(HWND handle, const int x, } } -void WinNativeEventFilter::moveWindowToDesktopCenter(HWND handle) { +void WinNativeEventFilter::moveWindowToDesktopCenter(const HWND handle) { + ResolveWin32APIs(); if (handle && m_lpIsWindow(handle)) { const WINDOWINFO windowInfo = GetInfoForWindow(handle); const MONITORINFO monitorInfo = GetMonitorInfoForWindow(handle); @@ -1646,3 +1670,46 @@ void WinNativeEventFilter::moveWindowToDesktopCenter(HWND handle) { ww, wh, TRUE); } } + +void WinNativeEventFilter::updateQtFrame(QWindow *const window, + const int titleBarHeight) { + if (window && (titleBarHeight > 0)) { + // Reduce top frame to zero since we paint it ourselves. Use + // device pixel to avoid rounding errors. + const QMargins margins = {0, -titleBarHeight, 0, 0}; + const QVariant marginsVar = QVariant::fromValue(margins); + // The dynamic property takes effect when creating the platform + // window. + window->setProperty("_q_windowsCustomMargins", marginsVar); + // If a platform window exists, change via native interface. + QPlatformWindow *platformWindow = window->handle(); + if (platformWindow) { + QGuiApplication::platformNativeInterface()->setWindowProperty( + platformWindow, QString::fromUtf8("WindowsCustomMargins"), + marginsVar); + } + } +} + +void WinNativeEventFilter::updateQtFrame_internal(const HWND handle) { + ResolveWin32APIs(); + if (handle && m_lpIsWindow(handle)) { + const int tbh = + getSystemMetric(handle, SystemMetric::TitleBarHeight, false); + const auto wid = reinterpret_cast(handle); +#ifdef QT_WIDGETS_LIB + const QWidget *const widget = QWidget::find(wid); + if (widget && widget->isTopLevel()) { + QWindow *const window = widget->windowHandle(); + if (window) { + updateQtFrame(window, tbh); + return; + } + } +#endif + QWindow *const window = QWindow::fromWinId(wid); + if (window) { + updateQtFrame(window, tbh); + } + } +} diff --git a/winnativeeventfilter.h b/winnativeeventfilter.h index 2499bca..c6fe692 100644 --- a/winnativeeventfilter.h +++ b/winnativeeventfilter.h @@ -34,6 +34,10 @@ #include #include +QT_BEGIN_NAMESPACE +QT_FORWARD_DECLARE_CLASS(QWindow) +QT_END_NAMESPACE + #if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0)) #define Q_DISABLE_MOVE(Class) \ Class(Class &&) = delete; \ @@ -70,53 +74,60 @@ public: // Frameless windows handle list static QVector framelessWindows(); - static void setFramelessWindows(QVector windows); + static void setFramelessWindows(const QVector &windows); // Make the given window become frameless. // The width and height will be scaled automatically according to DPI. Don't // scale them yourself. Just pass the original value. If you don't want to // change them, pass negative values to the parameters. - static void addFramelessWindow(HWND window, + static void addFramelessWindow(const HWND window, const WINDOWDATA *data = nullptr, - bool center = false, int x = -1, int y = -1, - int width = -1, int height = -1); - static void removeFramelessWindow(HWND window); + const bool center = false, const int x = -1, + const int y = -1, const int width = -1, + const int height = -1); + static void removeFramelessWindow(const HWND window); static void clearFramelessWindows(); // Set borderWidth, borderHeight or titleBarHeight to a negative value to // restore default behavior. // Note that it can only affect one specific window. // If you want to change these values globally, use setBorderWidth instead. - static void setWindowData(HWND window, const WINDOWDATA *data); + static void setWindowData(const HWND window, const WINDOWDATA *data); // You can modify the given window's data directly, it's the same with using // setWindowData. - static WINDOWDATA *windowData(HWND window); + static WINDOWDATA *windowData(const HWND window); // Change settings globally, not a specific window. // These values will be scaled automatically according to DPI, don't scale // them yourself. Just pass the original value. - static void setBorderWidth(int bw); - static void setBorderHeight(int bh); - static void setTitleBarHeight(int tbh); + static void setBorderWidth(const int bw); + static void setBorderHeight(const int bh); + static void setTitleBarHeight(const int tbh); // System metric value of the given window (if the pointer is null, // return the system's standard value). - static int getSystemMetric(HWND handle, SystemMetric metric, - bool dpiAware = true); + static int getSystemMetric(const HWND handle, const SystemMetric metric, + const bool dpiAware = true); // Use this function to trigger a frame change event or redraw a // specific window. Useful when you want to let some changes // in effect immediately. - static void updateWindow(HWND handle, bool triggerFrameChange = true, - bool redraw = true); + static void updateWindow(const HWND handle, + const bool triggerFrameChange = true, + const bool redraw = true); // Change the geometry of a window through Win32 API. // The width and height will be scaled automatically according to DPI. So // just pass the original value. - static void setWindowGeometry(HWND handle, const int x, const int y, + static void setWindowGeometry(const HWND handle, const int x, const int y, const int width, const int height); // Move the window to the center of the desktop. - static void moveWindowToDesktopCenter(HWND handle); + static void moveWindowToDesktopCenter(const HWND handle); + + // Update Qt's internal data about the window frame, otherwise Qt will + // take the size of the window frame into account when anyone is trying to + // change the geometry of the window. That's not what we want. + static void updateQtFrame(QWindow *const window, const int titleBarHeight); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) bool nativeEventFilter(const QByteArray &eventType, void *message, @@ -131,4 +142,6 @@ private: // will happen. static void install(); static void uninstall(); + + static void updateQtFrame_internal(const HWND handle); };