Zhao Yuhang
2023-12-22 e331fb1feda8891baba2a2dc1caeed67834d9d93
improve dark mode on win
3个文件已修改
62 ■■■■■ 已修改文件
src/core/contexts/win32windowcontext.cpp 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/qwindowkit_windows.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/shared/qwkwindowsextra_p.h 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core/contexts/win32windowcontext.cpp
@@ -937,18 +937,24 @@
            if (!isWin101809OrGreater()) {
                return false;
            }
            BOOL enable = attribute.toBool();
            if (isWin101903OrGreater()) {
                apis.pSetPreferredAppMode(enable ? PAM_AUTO : PAM_DEFAULT);
            } else {
                apis.pAllowDarkModeForApp(enable);
            }
            for (const auto attr : {
                    _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1,
                    _DWMWA_USE_IMMERSIVE_DARK_MODE,
            }) {
                apis.pDwmSetWindowAttribute(hwnd, attr, &enable, sizeof(enable));
            }
            WINDOWCOMPOSITIONATTRIBDATA wcad{};
            wcad.Attrib = WCA_USEDARKMODECOLORS;
            wcad.pvData = &enable;
            wcad.cbData = sizeof(enable);
            apis.pSetWindowCompositionAttribute(hwnd, &wcad);
            apis.pFlushMenuThemes();
            return true;
        }
        return false;
src/core/qwindowkit_windows.h
@@ -65,6 +65,13 @@
                rovi.dwBuildNumber >= 22000);
    }
    inline bool IsWindows101903OrGreater_Real() {
        RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
        return (rovi.dwMajorVersion > 10) ||
               (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 &&
                rovi.dwBuildNumber >= 18362);
    }
    inline bool IsWindows101809OrGreater_Real() {
        RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
        return (rovi.dwMajorVersion > 10) ||
src/core/shared/qwkwindowsextra_p.h
@@ -132,7 +132,24 @@
    };
    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.
        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_MAX = 4
    };
    using SetWindowCompositionAttributePtr = BOOL(WINAPI *)(HWND, PWINDOWCOMPOSITIONATTRIBDATA);
    // 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
    // Win10 1903 (10.0.18362)
    using SetPreferredAppModePtr = PREFERRED_APP_MODE(WINAPI *)(PREFERRED_APP_MODE); // Ordinal 135
    namespace {
@@ -161,6 +178,11 @@
#undef DYNAMIC_API_DECLARE
            SetWindowCompositionAttributePtr pSetWindowCompositionAttribute = nullptr;
            RefreshImmersiveColorPolicyStatePtr pRefreshImmersiveColorPolicyState = nullptr;
            AllowDarkModeForWindowPtr pAllowDarkModeForWindow = nullptr;
            AllowDarkModeForAppPtr pAllowDarkModeForApp = nullptr;
            FlushMenuThemesPtr pFlushMenuThemes = nullptr;
            SetPreferredAppModePtr pSetPreferredAppMode = nullptr;
        private:
            DynamicApis() {
@@ -190,6 +212,18 @@
                DYNAMIC_API_RESOLVE(winmm, timeEndPeriod);
#undef DYNAMIC_API_RESOLVE
#define UNDOC_API_RESOLVE(DLL, NAME, ORDINAL)                                                             \
    p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(MAKEINTRESOURCEA(ORDINAL)))
                QSystemLibrary uxtheme(QStringLiteral("uxtheme"));
                UNDOC_API_RESOLVE(uxtheme, RefreshImmersiveColorPolicyState, 104);
                UNDOC_API_RESOLVE(uxtheme, AllowDarkModeForWindow, 133);
                UNDOC_API_RESOLVE(uxtheme, AllowDarkModeForApp, 135);
                UNDOC_API_RESOLVE(uxtheme, FlushMenuThemes, 136);
                UNDOC_API_RESOLVE(uxtheme, SetPreferredAppMode, 135);
#undef UNDOC_API_RESOLVE
            }
            ~DynamicApis() = default;
@@ -299,6 +333,11 @@
        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;