Zhao Yuhang
2023-12-11 2f6c83c095724bbba0f43b2f2893ba73c17949a6
src/core/contexts/win32windowcontext.cpp
@@ -1,13 +1,15 @@
#include "win32windowcontext_p.h"
#include "qwkcoreglobal_p.h"
#include <optional>
#include <QtCore/QHash>
#include <QtCore/QAbstractNativeEventFilter>
#include <QtCore/QScopeGuard>
#include <QtGui/QGuiApplication>
#include <QtGui/QPainter>
#include <QtGui/QPalette>
#include <QtGui/QStyleHints>
#include <QtCore/private/qwinregistry_p.h>
#include <QtCore/private/qsystemlibrary_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
@@ -23,14 +25,36 @@
#include <shellscalingapi.h>
#include <dwmapi.h>
#include <timeapi.h>
#include <versionhelpers.h>
#include "nativeeventfilter.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_DECLARE_METATYPE(QMargins)
#endif
namespace QWK {
    using _DWMWINDOWATTRIBUTE = enum _DWMWINDOWATTRIBUTE
    {
        _DWMWA_USE_HOSTBACKDROPBRUSH = 17, // [set] BOOL, Allows the use of host backdrop brushes for the window.
        _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19, // Undocumented, the same with DWMWA_USE_IMMERSIVE_DARK_MODE, but available on systems before Win10 20H1.
        _DWMWA_USE_IMMERSIVE_DARK_MODE = 20, // [set] BOOL, Allows a window to either use the accent color, or dark, according to the user Color Mode preferences.
        _DWMWA_WINDOW_CORNER_PREFERENCE = 33, // [set] WINDOW_CORNER_PREFERENCE, Controls the policy that rounds top-level window corners
        _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37, // [get] UINT, width of the visible border around a thick frame window
        _DWMWA_SYSTEMBACKDROP_TYPE = 38, // [get, set] SYSTEMBACKDROP_TYPE, Controls the system-drawn backdrop material of a window, including behind the non-client area.
        _DWMWA_MICA_EFFECT = 1029 // Undocumented, use this value to enable Mica material on Win11 21H2. You should use DWMWA_SYSTEMBACKDROP_TYPE instead on Win11 22H2 and newer.
    };
    // The thickness of an auto-hide taskbar in pixels.
    static constexpr const auto kAutoHideTaskBarThickness = quint8{2};
    static inline constexpr const auto kFrameBorderActiveColorLight =
        QColor{110, 110, 110};                                                           // #6E6E6E
    static inline constexpr const auto kFrameBorderActiveColorDark = QColor{51, 51, 51}; // #333333
    static inline constexpr const auto kFrameBorderInactiveColorLight =
        QColor{167, 167, 167};                                                           // #A7A7A7
    static inline constexpr const auto kFrameBorderInactiveColorDark =
        QColor{61, 61, 62};                                                              // #3D3D3E
    // hWnd -> context
    using WndProcHash = QHash<HWND, Win32WindowContext *>;
@@ -50,6 +74,11 @@
    } g_hook{};
    struct DynamicApis {
        static const DynamicApis &instance() {
            static const DynamicApis inst{};
            return inst;
        }
//        template <typename T>
//        struct DefaultFunc;
//
@@ -60,12 +89,15 @@
//            }
//        };
//
// #define DYNAMIC_API_DECLARE(NAME) decltype(&::NAME) p##NAME = DefaultFunc<decltype(&::NAME)>::func
// #define DYNAMIC_API_DECLARE(NAME) decltype(&::NAME) p##NAME =
// DefaultFunc<decltype(&::NAME)>::func
#define DYNAMIC_API_DECLARE(NAME) decltype(&::NAME) p##NAME = nullptr
        DYNAMIC_API_DECLARE(DwmFlush);
        DYNAMIC_API_DECLARE(DwmIsCompositionEnabled);
        DYNAMIC_API_DECLARE(DwmGetCompositionTimingInfo);
        DYNAMIC_API_DECLARE(DwmGetWindowAttribute);
        DYNAMIC_API_DECLARE(GetDpiForWindow);
        DYNAMIC_API_DECLARE(GetSystemMetricsForDpi);
        DYNAMIC_API_DECLARE(GetDpiForMonitor);
@@ -75,8 +107,10 @@
#undef DYNAMIC_API_DECLARE
    private:
        DynamicApis() {
#define DYNAMIC_API_RESOLVE(DLL, NAME) p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL##.resolve(#NAME))
#define DYNAMIC_API_RESOLVE(DLL, NAME)                                                             \
    p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(#NAME))
            QSystemLibrary user32(QStringLiteral("user32"));
            DYNAMIC_API_RESOLVE(user32, GetDpiForWindow);
@@ -89,6 +123,7 @@
            DYNAMIC_API_RESOLVE(dwmapi, DwmFlush);
            DYNAMIC_API_RESOLVE(dwmapi, DwmIsCompositionEnabled);
            DYNAMIC_API_RESOLVE(dwmapi, DwmGetCompositionTimingInfo);
            DYNAMIC_API_RESOLVE(dwmapi, DwmGetWindowAttribute);
            QSystemLibrary winmm(QStringLiteral("winmm"));
            DYNAMIC_API_RESOLVE(winmm, timeGetDevCaps);
@@ -100,12 +135,6 @@
        ~DynamicApis() = default;
        static const DynamicApis &instance() {
            static const DynamicApis inst{};
            return inst;
        }
    private:
        Q_DISABLE_COPY_MOVE(DynamicApis)
    };
@@ -190,22 +219,22 @@
    }
    static inline bool isWin8OrGreater() {
        static const bool result = ::IsWindows8OrGreater();
        static const bool result = IsWindows8OrGreater_Real();
        return result;
    }
    static inline bool isWin8Point1OrGreater() {
        static const bool result = ::IsWindows8Point1OrGreater();
        static const bool result = IsWindows8Point1OrGreater_Real();
        return result;
    }
    static inline bool isWin10OrGreater() {
        static const bool result = ::IsWindows10OrGreater();
        static const bool result = IsWindows10OrGreater_Real();
        return result;
    }
    static inline bool isWin11OrGreater() {
        static const bool result = ::IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN10), LOBYTE(_WIN32_WINNT_WIN10), 22000);
        static const bool result = IsWindows11OrGreater_Real();
        return result;
    }
@@ -219,6 +248,69 @@
        }
        BOOL enabled = FALSE;
        return SUCCEEDED(apis.pDwmIsCompositionEnabled(&enabled)) && enabled;
    }
    static inline bool isWindowFrameBorderColorized() {
        const QWinRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
        if (!registry.isValid()) {
            return false;
        }
        const auto value = registry.dwordValue(L"ColorPrevalence");
        if (!value.second) {
            return false;
        }
        return value.first;
    }
    static inline bool isDarkThemeActive() {
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
        return QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark;
#else
        const QWinRegistryKey registry(
            HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)");
        if (!registry.isValid()) {
            return false;
        }
        const auto value = registry.dwordValue(L"AppsUseLightTheme");
        if (!value.second) {
            return false;
        }
        return !value.first;
#endif
    }
    static inline bool isDarkWindowFrameEnabled(HWND hwnd) {
        BOOL enabled = FALSE;
        const DynamicApis &apis = DynamicApis::instance();
        if (SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, _DWMWA_USE_IMMERSIVE_DARK_MODE, &enabled, sizeof(enabled)))) {
            return enabled;
        } else if (SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, &enabled, sizeof(enabled)))) {
            return enabled;
        } else {
            return false;
        }
    }
    static inline QColor getAccentColor() {
#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
        return QGuiApplication::palette().color(QPalette::Accent);
#else
        const QWinRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
        if (!registry.isValid()) {
            return {};
        }
        const auto value = registry.dwordValue(L"AccentColor");
        if (!value.second) {
            return {};
        }
        // The retrieved value is in the #AABBGGRR format, we need to
        // convert it to the #AARRGGBB format which Qt expects.
        const QColor abgr = QColor::fromRgba(value.first);
        if (!abgr.isValid()) {
            return {};
        }
        return QColor::fromRgb(abgr.blue(), abgr.green(), abgr.red(), abgr.alpha());
#endif
    }
    static inline void triggerFrameChange(HWND hwnd) {
@@ -240,9 +332,21 @@
        } else { // Win2K
            HDC hdc = ::GetDC(nullptr);
            const int dpiX = ::GetDeviceCaps(hdc, LOGPIXELSX);
            const int dpiY = ::GetDeviceCaps(hdc, LOGPIXELSY);
            //const int dpiY = ::GetDeviceCaps(hdc, LOGPIXELSY);
            ::ReleaseDC(nullptr, hdc);
            return quint32(dpiX);
        }
    }
    static inline quint32 getWindowFrameBorderThickness(HWND hwnd) {
        UINT result{ 0 };
        const DynamicApis &apis = DynamicApis::instance();
        if (SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, &result, sizeof(result)))) {
            return result;
        } else {
            const quint32 dpi = getDpiForWindow(hwnd);
            result = quint32(std::round(qreal(1) * qreal(dpi) / qreal(USER_DEFAULT_SCREEN_DPI)));
            return result;
        }
    }
@@ -272,11 +376,11 @@
    static inline void updateInternalWindowFrameMargins(HWND hwnd, QWindow *window) {
        const auto margins = [hwnd]() -> QMargins {
            const int titleBarHeight = getTitleBarHeight(hwnd);
            const auto titleBarHeight = int(getTitleBarHeight(hwnd));
            if (isWin10OrGreater()) {
                return {0, -titleBarHeight, 0, 0};
            } else {
                const int frameSize = getResizeBorderThickness(hwnd);
                const auto frameSize = int(getResizeBorderThickness(hwnd));
                return {-frameSize, -titleBarHeight, -frameSize, -frameSize};
            }
        }();
@@ -381,8 +485,8 @@
        apis.ptimeEndPeriod(ms_granularity);
    }
    static inline void showSystemMenu2(HWND hWnd, const POINT &pos, const bool selectFirstEntry)
    {
    static inline void showSystemMenu2(HWND hWnd, const POINT &pos, const bool selectFirstEntry,
                                       const bool fixedSize) {
        const HMENU hMenu = ::GetSystemMenu(hWnd, FALSE);
        if (!hMenu) {
            // The corresponding window doesn't have a system menu, most likely due to the
@@ -391,97 +495,53 @@
            return;
        }
        // Tweak the menu items according to the current window status and user settings.
        const bool disableClose = /*data->callbacks->getProperty(kSysMenuDisableCloseVar, false).toBool()*/false;
        const bool disableRestore = /*data->callbacks->getProperty(kSysMenuDisableRestoreVar, false).toBool()*/false;
        const bool disableMinimize = /*data->callbacks->getProperty(kSysMenuDisableMinimizeVar, false).toBool()*/false;
        const bool disableMaximize = /*data->callbacks->getProperty(kSysMenuDisableMaximizeVar, false).toBool()*/false;
        const bool disableSize = /*data->callbacks->getProperty(kSysMenuDisableSizeVar, false).toBool()*/false;
        const bool disableMove = /*data->callbacks->getProperty(kSysMenuDisableMoveVar, false).toBool()*/false;
        const bool removeClose = /*data->callbacks->getProperty(kSysMenuRemoveCloseVar, false).toBool()*/false;
        const bool removeSeparator = /*data->callbacks->getProperty(kSysMenuRemoveSeparatorVar, false).toBool()*/false;
        const bool removeRestore = /*data->callbacks->getProperty(kSysMenuRemoveRestoreVar, false).toBool()*/false;
        const bool removeMinimize = /*data->callbacks->getProperty(kSysMenuRemoveMinimizeVar, false).toBool()*/false;
        const bool removeMaximize = /*data->callbacks->getProperty(kSysMenuRemoveMaximizeVar, false).toBool()*/false;
        const bool removeSize = /*data->callbacks->getProperty(kSysMenuRemoveSizeVar, false).toBool()*/false;
        const bool removeMove = /*data->callbacks->getProperty(kSysMenuRemoveMoveVar, false).toBool()*/false;
        const bool maxOrFull = IsMaximized(hWnd) || isFullScreen(hWnd);
        const bool fixedSize = /*data->callbacks->isWindowFixedSize()*/false;
        if (removeClose) {
            ::DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
        } else {
            ::EnableMenuItem(hMenu, SC_CLOSE, (MF_BYCOMMAND | (disableClose ? MFS_DISABLED : MFS_ENABLED)));
        }
        if (removeSeparator) {
            // Looks like we must use 0 for the second parameter here, otherwise we can't remove the separator.
            ::DeleteMenu(hMenu, 0, MFT_SEPARATOR);
        }
        if (removeMaximize) {
            ::DeleteMenu(hMenu, SC_MAXIMIZE, MF_BYCOMMAND);
        } else {
            ::EnableMenuItem(hMenu, SC_MAXIMIZE, (MF_BYCOMMAND | ((maxOrFull || fixedSize || disableMaximize) ? MFS_DISABLED : MFS_ENABLED)));
        }
        if (removeRestore) {
            ::DeleteMenu(hMenu, SC_RESTORE, MF_BYCOMMAND);
        } else {
            ::EnableMenuItem(hMenu, SC_RESTORE, (MF_BYCOMMAND | ((maxOrFull && !fixedSize && !disableRestore) ? MFS_ENABLED : MFS_DISABLED)));
            // The first menu item should be selected by default if the menu is brought
            // up by keyboard. I don't know how to pre-select a menu item but it seems
            // highlight can do the job. However, there's an annoying issue if we do
            // this manually: the highlighted menu item is really only highlighted,
            // not selected, so even if the mouse cursor hovers on other menu items
            // or the user navigates to other menu items through keyboard, the original
            // highlight bar will not move accordingly, the OS will generate another
            // highlight bar to indicate the current selected menu item, which will make
            // the menu look kind of weird. Currently I don't know how to fix this issue.
            ::HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | (selectFirstEntry ? MFS_HILITE : MFS_UNHILITE)));
        }
        if (removeMinimize) {
            ::DeleteMenu(hMenu, SC_MINIMIZE, MF_BYCOMMAND);
        } else {
            ::EnableMenuItem(hMenu, SC_MINIMIZE, (MF_BYCOMMAND | (disableMinimize ? MFS_DISABLED : MFS_ENABLED)));
        }
        if (removeSize) {
            ::DeleteMenu(hMenu, SC_SIZE, MF_BYCOMMAND);
        } else {
            ::EnableMenuItem(hMenu, SC_SIZE, (MF_BYCOMMAND | ((maxOrFull || fixedSize || disableSize || disableMinimize || disableMaximize) ? MFS_DISABLED : MFS_ENABLED)));
        }
        if (removeMove) {
            ::DeleteMenu(hMenu, SC_MOVE, MF_BYCOMMAND);
        } else {
            ::EnableMenuItem(hMenu, SC_MOVE, (MF_BYCOMMAND | ((maxOrFull || disableMove) ? MFS_DISABLED : MFS_ENABLED)));
        }
        ::EnableMenuItem(hMenu, SC_CLOSE, (MF_BYCOMMAND | MFS_ENABLED));
        ::EnableMenuItem(hMenu, SC_MAXIMIZE,
                         (MF_BYCOMMAND | ((maxOrFull || fixedSize) ? MFS_DISABLED : MFS_ENABLED)));
        ::EnableMenuItem(hMenu, SC_RESTORE,
                         (MF_BYCOMMAND | ((maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
        // The first menu item should be selected by default if the menu is brought
        // up by keyboard. I don't know how to pre-select a menu item but it seems
        // highlight can do the job. However, there's an annoying issue if we do
        // this manually: the highlighted menu item is really only highlighted,
        // not selected, so even if the mouse cursor hovers on other menu items
        // or the user navigates to other menu items through keyboard, the original
        // highlight bar will not move accordingly, the OS will generate another
        // highlight bar to indicate the current selected menu item, which will make
        // the menu look kind of weird. Currently I don't know how to fix this issue.
        ::HiliteMenuItem(hWnd, hMenu, SC_RESTORE,
                         (MF_BYCOMMAND | (selectFirstEntry ? MFS_HILITE : MFS_UNHILITE)));
        ::EnableMenuItem(hMenu, SC_MINIMIZE, (MF_BYCOMMAND | MFS_ENABLED));
        ::EnableMenuItem(hMenu, SC_SIZE,
                         (MF_BYCOMMAND | ((maxOrFull || fixedSize) ? MFS_DISABLED : MFS_ENABLED)));
        ::EnableMenuItem(hMenu, SC_MOVE, (MF_BYCOMMAND | (maxOrFull ? MFS_DISABLED : MFS_ENABLED)));
        // The default menu item will appear in bold font. There can only be one default
        // menu item per menu at most. Set the item ID to "UINT_MAX" (or simply "-1")
        // can clear the default item for the given menu.
        std::optional<UINT> defaultItemId = std::nullopt;
        UINT defaultItemId = UINT_MAX;
        if (isWin11OrGreater()) {
            if (maxOrFull) {
                if (!removeRestore) {
                    defaultItemId = SC_RESTORE;
                }
                defaultItemId = SC_RESTORE;
            } else {
                if (!removeMaximize) {
                    defaultItemId = SC_MAXIMIZE;
                }
                defaultItemId = SC_MAXIMIZE;
            }
        }
        if (!(defaultItemId.has_value() || removeClose)) {
        if (defaultItemId == UINT_MAX) {
            defaultItemId = SC_CLOSE;
        }
        ::SetMenuDefaultItem(hMenu, defaultItemId.value_or(UINT_MAX), FALSE);
        //::DrawMenuBar(hWnd);
        ::SetMenuDefaultItem(hMenu, defaultItemId, FALSE);
        // Popup the system menu at the required position.
        const auto result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), pos.x, pos.y, 0, hWnd, nullptr);
        const auto result = ::TrackPopupMenu(
            hMenu,
            (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)),
            pos.x, pos.y, 0, hWnd, nullptr);
        if (!removeRestore) {
            // Unhighlight the first menu item after the popup menu is closed, otherwise it will keep
            // highlighting until we unhighlight it manually.
            ::HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | MFS_UNHILITE));
        }
        // Unhighlight the first menu item after the popup menu is closed, otherwise it will keep
        // highlighting until we unhighlight it manually.
        ::HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | MFS_UNHILITE));
        if (!result) {
            // The user canceled the menu, no need to continue.
@@ -516,7 +576,8 @@
            case HTBORDER:
                return Win32WindowContext::FixedBorder;
            default:
                break; // unreachable
                // unreachable
                break;
        }
        return Win32WindowContext::Outside;
    }
@@ -560,7 +621,7 @@
    // DefWindowProc(). Consequently, we have to add a global native filter that forwards the result
    // of the hook function, telling Qt whether we have filtered the events before. Since Qt only
    // handles Windows window messages in the main thread, it is safe to do so.
    class WindowsNativeEventFilter : public QAbstractNativeEventFilter {
    class WindowsNativeEventFilter : public NativeEventFilter {
    public:
        bool nativeEventFilter(const QByteArray &eventType, void *message,
                               QT_NATIVE_EVENT_RESULT_TYPE *result) override {
@@ -595,14 +656,12 @@
                return;
            }
            instance = new WindowsNativeEventFilter();
            installNativeEventFilter(instance);
        }
        static inline void uninstall() {
            if (!instance) {
                return;
            }
            removeNativeEventFilter(instance);
            delete instance;
            instance = nullptr;
        }
@@ -710,6 +769,85 @@
        }
    }
    QString Win32WindowContext::key() const {
        return QStringLiteral("win32");
    }
    void Win32WindowContext::virtual_hook(int id, void *data) {
        switch (id) {
            case CentralizeHook: {
                const auto hwnd = reinterpret_cast<HWND>(m_windowHandle->winId());
                moveToDesktopCenter(hwnd);
                return;
            }
            case ShowSystemMenuHook: {
                const auto &pos = *static_cast<const QPoint *>(data);
                auto hWnd = reinterpret_cast<HWND>(m_windowHandle->winId());
                showSystemMenu2(hWnd, qpoint2point(pos), false,
                                m_delegate->isHostSizeFixed(m_host));
                return;
            }
            case NeedsDrawBordersHook: {
                auto &result = *static_cast<bool *>(data);
                result = isWin10OrGreater() && !isWin11OrGreater();
                return;
            }
            case DrawBordersHook: {
                auto args = static_cast<void **>(data);
                auto &painter = *static_cast<QPainter *>(args[0]);
                const auto &rect = *static_cast<const QRect *>(args[1]);
                const auto &region = *static_cast<const QRegion *>(args[2]);
                const auto hwnd = reinterpret_cast<HWND>(m_windowHandle->winId());
                QPen pen{};
                const auto borderThickness = int(QHighDpi::fromNativePixels(getWindowFrameBorderThickness(hwnd), m_windowHandle));
                pen.setWidth(borderThickness * 2);
                const bool active = m_host->isWidgetType() ? m_host->property("isActiveWindow").toBool() : m_host->property("active").toBool();
                const bool dark = isDarkThemeActive() && isDarkWindowFrameEnabled(hwnd);
                if (active) {
                    if (isWindowFrameBorderColorized()) {
                        pen.setColor(getAccentColor());
                    } else {
                        if (dark) {
                            pen.setColor(kFrameBorderActiveColorDark);
                        } else {
                            pen.setColor(kFrameBorderActiveColorLight);
                        }
                    }
                } else {
                    if (dark) {
                        pen.setColor(kFrameBorderInactiveColorDark);
                    } else {
                        pen.setColor(kFrameBorderInactiveColorLight);
                    }
                }
                painter.save();
                painter.setRenderHint(QPainter::Antialiasing); // ### TODO: do we need to enable or disable it?
                painter.setPen(pen);
                painter.drawLine(QLine{ QPoint{ 0, 0 }, QPoint{ rect.width(), 0 } });
                painter.restore();
                return;
            }
            case QueryBorderThicknessHook: {
                auto args = static_cast<void **>(data);
                const bool requireNative = *static_cast<const bool *>(args[0]);
                quint32 &thickness = *static_cast<quint32 *>(args[1]);
                const auto hwnd = reinterpret_cast<HWND>(m_windowHandle->winId());
                const auto nativeThickness = getWindowFrameBorderThickness(hwnd);
                if (requireNative) {
                    thickness = nativeThickness;
                } else {
                    thickness = QHighDpi::fromNativePixels(nativeThickness, m_windowHandle);
                }
                return;
            }
            default: {
                // unreachable
                break;
            }
        }
        AbstractWindowContext::virtual_hook(id, data);
    }
    bool Win32WindowContext::setupHost() {
        // Install window hook
        auto winId = m_windowHandle->winId();
@@ -777,11 +915,10 @@
        return false; // Not handled
    }
    static constexpr const auto kMessageTag = WPARAM(0x97CCEA99);
    static inline constexpr bool isTaggedMessage(WPARAM wParam) {
        return (wParam == kMessageTag);
    }
    static constexpr const struct {
        const WPARAM wParam = 0xF1C9ADD4;
        const LPARAM lParam = 0xAFB6F4C6;
    } kMessageTag;
    static inline quint64 getKeyState() {
        quint64 result = 0;
@@ -821,7 +958,7 @@
                // wParam is always ignored in mouse leave messages, but here we
                // give them a special tag to be able to distinguish which messages
                // are sent by ourselves.
                return kMessageTag;
                return kMessageTag.wParam;
            }
            const quint64 keyState = getKeyState();
            if ((myMsg >= WM_NCXBUTTONDOWN) && (myMsg <= WM_NCXBUTTONDBLCLK)) {
@@ -899,6 +1036,7 @@
                SEND_MESSAGE(hWnd, WM_MOUSELEAVE, wParamNew, lParamNew);
                break;
            default:
                // unreachable
                break;
        }
@@ -921,7 +1059,7 @@
                                               LPARAM lParam, LRESULT *result) {
        switch (message) {
            case WM_MOUSELEAVE: {
                if (!isTaggedMessage(wParam)) {
                if (wParam == kMessageTag.wParam) {
                    // Qt will call TrackMouseEvent() to get the WM_MOUSELEAVE message when it
                    // receives WM_MOUSEMOVE messages, and since we are converting every
                    // WM_NCMOUSEMOVE message to WM_MOUSEMOVE message and send it back to the window
@@ -933,9 +1071,9 @@
                    DWORD dwScreenPos = ::GetMessagePos();
                    POINT screenPoint{GET_X_LPARAM(dwScreenPos), GET_Y_LPARAM(dwScreenPos)};
                    ::ScreenToClient(hWnd, &screenPoint);
                    QPoint qtScenePos = QHighDpi::fromNativeLocalPosition(
                        QPoint{screenPoint.x, screenPoint.y}, m_windowHandle);
                    auto dummy = CoreWindowAgent::Unknown;
                    QPoint qtScenePos = QHighDpi::fromNativeLocalPosition(point2qpoint(screenPoint),
                                                                          m_windowHandle);
                    auto dummy = WindowAgentBase::Unknown;
                    if (isInSystemButtons(qtScenePos, &dummy)) {
                        // We must record whether the last WM_MOUSELEAVE was filtered, because if
                        // Qt does not receive this message it will not call TrackMouseEvent()
@@ -1166,14 +1304,14 @@
                auto clientWidth = RECT_WIDTH(clientRect);
                auto clientHeight = RECT_HEIGHT(clientRect);
                QPoint qtScenePos = QHighDpi::fromNativeLocalPosition(
                    QPoint(nativeLocalPos.x, nativeLocalPos.y), m_windowHandle);
                QPoint qtScenePos =
                    QHighDpi::fromNativeLocalPosition(point2qpoint(nativeLocalPos), m_windowHandle);
                bool isFixedSize = m_delegate->isHostSizeFixed(m_host);
                bool isTitleBar = isInTitleBarDraggableArea(qtScenePos);
                bool dontOverrideCursor = false; // ### TODO
                CoreWindowAgent::SystemButton sysButtonType = CoreWindowAgent::Unknown;
                WindowAgentBase::SystemButton sysButtonType = WindowAgentBase::Unknown;
                if (!isFixedSize && isInSystemButtons(qtScenePos, &sysButtonType)) {
                    // Firstly, we set the hit test result to a default value to be able to detect
                    // whether we have changed it or not afterwards.
@@ -1217,23 +1355,24 @@
                        // exact role of our button. The Snap Layout feature introduced in Windows
                        // 11 won't work without this.
                        switch (sysButtonType) {
                            case CoreWindowAgent::WindowIcon:
                            case WindowAgentBase::WindowIcon:
                                *result = HTSYSMENU;
                                break;
                            case CoreWindowAgent::Help:
                            case WindowAgentBase::Help:
                                *result = HTHELP;
                                break;
                            case CoreWindowAgent::Minimize:
                            case WindowAgentBase::Minimize:
                                *result = HTREDUCE;
                                break;
                            case CoreWindowAgent::Maximize:
                            case WindowAgentBase::Maximize:
                                *result = HTZOOM;
                                break;
                            case CoreWindowAgent::Close:
                            case WindowAgentBase::Close:
                                *result = HTCLOSE;
                                break;
                            default:
                                break; // unreachable
                                // unreachable
                                break;
                        }
                    }
                    if (*result == HTNOWHERE) {
@@ -1679,7 +1818,8 @@
            }();
            RECT windowPos{};
            ::GetWindowRect(hWnd, &windowPos);
            return {static_cast<LONG>(windowPos.left + horizontalOffset), static_cast<LONG>(windowPos.top + verticalOffset)};
            return {static_cast<LONG>(windowPos.left + horizontalOffset),
                    static_cast<LONG>(windowPos.top + verticalOffset)};
        };
        bool shouldShowSystemMenu = false;
        bool broughtByKeyboard = false;
@@ -1687,7 +1827,8 @@
        switch (message) {
            case WM_RBUTTONUP: {
                const POINT nativeLocalPos = getNativePosFromMouse();
                const QPoint qtScenePos = QHighDpi::fromNativeLocalPosition(QPoint(nativeLocalPos.x, nativeLocalPos.y), m_windowHandle);
                const QPoint qtScenePos =
                    QHighDpi::fromNativeLocalPosition(point2qpoint(nativeLocalPos), m_windowHandle);
                if (isInTitleBarDraggableArea(qtScenePos)) {
                    shouldShowSystemMenu = true;
                    nativeGlobalPos = nativeLocalPos;
@@ -1726,7 +1867,8 @@
                break;
        }
        if (shouldShowSystemMenu) {
            showSystemMenu2(hWnd, nativeGlobalPos, broughtByKeyboard);
            showSystemMenu2(hWnd, nativeGlobalPos, broughtByKeyboard,
                            m_delegate->isHostSizeFixed(m_host));
            // QPA's internal code will handle system menu events separately, and its
            // behavior is not what we would want to see because it doesn't know our
            // window doesn't have any window frame now, so return early here to avoid