Sine Striker
2023-12-29 6eb2efea00eb07ce3a6b089b984885ce4a08c9ca
src/core/shared/qwkwindowsextra_p.h
@@ -15,9 +15,7 @@
#include <timeapi.h>
#include <QWKCore/qwindowkit_windows.h>
#include <QtCore/private/qsystemlibrary_p.h>
#include <QtCore/private/qwinregistry_p.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QStyleHints>
@@ -132,12 +130,14 @@
    };
    using PWINDOWCOMPOSITIONATTRIBDATA = WINDOWCOMPOSITIONATTRIBDATA *;
    enum PREFERRED_APP_MODE
    {
        PAM_DEFAULT = 0, // Default behavior on systems before Win10 1809. It indicates the application doesn't support dark mode at all.
        PAM_AUTO = 1, // Available since Win10 1809, let system decide whether to enable dark mode or not.
    enum PREFERRED_APP_MODE {
        PAM_DEFAULT = 0, // Default behavior on systems before Win10 1809. It indicates the
                         // application doesn't support dark mode at all.
        PAM_AUTO =
            1, // Available since Win10 1809, let system decide whether to enable dark mode or not.
        PAM_DARK = 2, // Available since Win10 1903, force dark mode regardless of the system theme.
        PAM_LIGHT = 3, // Available since Win10 1903, force light mode regardless of the system theme.
        PAM_LIGHT =
            3, // Available since Win10 1903, force light mode regardless of the system theme.
        PAM_MAX = 4
    };
@@ -145,9 +145,9 @@
    // Win10 1809 (10.0.17763)
    using RefreshImmersiveColorPolicyStatePtr = VOID(WINAPI *)(VOID); // Ordinal 104
    using AllowDarkModeForWindowPtr = BOOL(WINAPI *)(HWND, BOOL); // Ordinal 133
    using AllowDarkModeForAppPtr = BOOL(WINAPI *)(BOOL); // Ordinal 135
    using FlushMenuThemesPtr = VOID(WINAPI *)(VOID); // Ordinal 136
    using AllowDarkModeForWindowPtr = BOOL(WINAPI *)(HWND, BOOL);     // Ordinal 133
    using AllowDarkModeForAppPtr = BOOL(WINAPI *)(BOOL);              // Ordinal 135
    using FlushMenuThemesPtr = VOID(WINAPI *)(VOID);                  // Ordinal 136
    // Win10 1903 (10.0.18362)
    using SetPreferredAppModePtr = PREFERRED_APP_MODE(WINAPI *)(PREFERRED_APP_MODE); // Ordinal 135
@@ -170,6 +170,7 @@
            DYNAMIC_API_DECLARE(DwmEnableBlurBehindWindow);
            DYNAMIC_API_DECLARE(GetDpiForWindow);
            DYNAMIC_API_DECLARE(GetSystemMetricsForDpi);
            DYNAMIC_API_DECLARE(AdjustWindowRectExForDpi);
            DYNAMIC_API_DECLARE(GetDpiForMonitor);
            DYNAMIC_API_DECLARE(timeGetDevCaps);
            DYNAMIC_API_DECLARE(timeBeginPeriod);
@@ -193,6 +194,7 @@
                DYNAMIC_API_RESOLVE(user32, GetDpiForWindow);
                DYNAMIC_API_RESOLVE(user32, GetSystemMetricsForDpi);
                DYNAMIC_API_RESOLVE(user32, SetWindowCompositionAttribute);
                DYNAMIC_API_RESOLVE(user32, AdjustWindowRectExForDpi);
                QSystemLibrary shcore(QStringLiteral("shcore"));
                DYNAMIC_API_RESOLVE(shcore, GetDpiForMonitor);
@@ -213,7 +215,7 @@
#undef DYNAMIC_API_RESOLVE
#define UNDOC_API_RESOLVE(DLL, NAME, ORDINAL)                                                             \
#define UNDOC_API_RESOLVE(DLL, NAME, ORDINAL)                                                      \
    p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(MAKEINTRESOURCEA(ORDINAL)))
                QSystemLibrary uxtheme(QStringLiteral("uxtheme"));
@@ -228,7 +230,7 @@
            ~DynamicApis() = default;
            Q_DISABLE_COPY_MOVE(DynamicApis)
            Q_DISABLE_COPY(DynamicApis)
        };
    }
@@ -302,6 +304,15 @@
                    LONG(qrect.bottom())};
    }
    static inline constexpr QMargins margins2qmargins(const MARGINS &margins) {
        return {margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth,
                margins.cyBottomHeight};
    }
    static inline constexpr MARGINS qmargins2margins(const QMargins &qmargins) {
        return {qmargins.left(), qmargins.right(), qmargins.top(), qmargins.bottom()};
    }
    static inline /*constexpr*/ QString hwnd2str(const WId windowId) {
        // NULL handle is allowed here.
        return QLatin1String("0x") +
@@ -311,41 +322,6 @@
    static inline /*constexpr*/ QString hwnd2str(HWND hwnd) {
        // NULL handle is allowed here.
        return hwnd2str(reinterpret_cast<WId>(hwnd));
    }
    static inline bool isWin8OrGreater() {
        static const bool result = IsWindows8OrGreater_Real();
        return result;
    }
    static inline bool isWin8Point1OrGreater() {
        static const bool result = IsWindows8Point1OrGreater_Real();
        return result;
    }
    static inline bool isWin10OrGreater() {
        static const bool result = IsWindows10OrGreater_Real();
        return result;
    }
    static inline bool isWin101809OrGreater() {
        static const bool result = IsWindows101809OrGreater_Real();
        return result;
    }
    static inline bool isWin101903OrGreater() {
        static const bool result = IsWindows101903OrGreater_Real();
        return result;
    }
    static inline bool isWin11OrGreater() {
        static const bool result = IsWindows11OrGreater_Real();
        return result;
    }
    static inline bool isWin1122H2OrGreater() {
        static const bool result = IsWindows1122H2OrGreater_Real();
        return result;
    }
    static inline bool isDwmCompositionEnabled() {
@@ -361,11 +337,11 @@
    }
    static inline bool isWindowFrameBorderColorized() {
        const QWinRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
        WindowsRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
        if (!registry.isValid()) {
            return false;
        }
        const auto value = registry.dwordValue(L"ColorPrevalence");
        auto value = registry.dwordValue(L"ColorPrevalence");
        if (!value.second) {
            return false;
        }
@@ -383,12 +359,12 @@
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
        return QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark;
#else
        const QWinRegistryKey registry(
        WindowsRegistryKey registry(
            HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)");
        if (!registry.isValid()) {
            return false;
        }
        const auto value = registry.dwordValue(L"AppsUseLightTheme");
        auto value = registry.dwordValue(L"AppsUseLightTheme");
        if (!value.second) {
            return false;
        }
@@ -406,33 +382,81 @@
                                                         _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1,
                                                         &enabled, sizeof(enabled)))) {
            return enabled;
        } else {
            return false;
        }
        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)");
        WindowsRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
        if (!registry.isValid()) {
            return {};
        }
        const auto value = registry.dwordValue(L"AccentColor");
        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()) {
        QColor color = QColor::fromRgba(value.first);
        if (!color.isValid()) {
            return {};
        }
        return QColor::fromRgb(abgr.blue(), abgr.green(), abgr.red(), abgr.alpha());
        return QColor::fromRgb(color.blue(), color.green(), color.red(), color.alpha());
#endif
    }
    static inline quint32 getDpiForWindow(HWND hwnd) {
        const DynamicApis &apis = DynamicApis::instance();
        if (apis.pGetDpiForWindow) {         // Win10
            return apis.pGetDpiForWindow(hwnd);
        } else if (apis.pGetDpiForMonitor) { // Win8.1
            HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
            UINT dpiX{0};
            UINT dpiY{0};
            apis.pGetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
            return dpiX;
        } else { // Win2K
            HDC hdc = ::GetDC(nullptr);
            const int dpiX = ::GetDeviceCaps(hdc, LOGPIXELSX);
            // const int dpiY = ::GetDeviceCaps(hdc, LOGPIXELSY);
            ::ReleaseDC(nullptr, hdc);
            return quint32(dpiX);
        }
    }
    static inline quint32 getSystemMetricsForDpi(int index, quint32 dpi) {
        const DynamicApis &apis = DynamicApis::instance();
        if (apis.pGetSystemMetricsForDpi) {
            return ::GetSystemMetricsForDpi(index, dpi);
        }
        return ::GetSystemMetrics(index);
    }
    static inline quint32 getWindowFrameBorderThickness(HWND hwnd) {
        const DynamicApis &apis = DynamicApis::instance();
        if (UINT result = 0; SUCCEEDED(apis.pDwmGetWindowAttribute(
                hwnd, _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, &result, sizeof(result)))) {
            return result;
        }
        return getSystemMetricsForDpi(SM_CXBORDER, getDpiForWindow(hwnd));
    }
    static inline quint32 getResizeBorderThickness(HWND hwnd) {
        const quint32 dpi = getDpiForWindow(hwnd);
        return getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) +
               getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
    }
    static inline quint32 getTitleBarHeight(HWND hwnd) {
        const quint32 dpi = getDpiForWindow(hwnd);
        return getSystemMetricsForDpi(SM_CYCAPTION, dpi) +
               getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) +
               getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
    }
}
#endif // QWKWINDOWSEXTRA_P_H