From e33059ee1ef7e1be07490ad0245676ded42589f4 Mon Sep 17 00:00:00 2001
From: Zhao Yuhang <2546789017@qq.com>
Date: 周五, 22 12月 2023 23:12:16 +0800
Subject: [PATCH] win: allow dynamic switch dark mode

---
 src/core/shared/qwkwindowsextra_p.h      |    5 +++++
 src/core/qwindowkit_windows.h            |    7 +++++++
 examples/mainwindow/mainwindow.cpp       |    4 ++++
 src/core/contexts/win32windowcontext.cpp |   27 +++++++++++++++++----------
 4 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/examples/mainwindow/mainwindow.cpp b/examples/mainwindow/mainwindow.cpp
index 7faf057..e693228 100644
--- a/examples/mainwindow/mainwindow.cpp
+++ b/examples/mainwindow/mainwindow.cpp
@@ -291,6 +291,10 @@
         return;
     currentTheme = theme;
 
+#ifdef Q_OS_WIN
+    windowAgent->setWindowAttribute(QStringLiteral("dark-mode"), currentTheme == Dark);
+#endif
+
     if (QFile qss(theme == Dark ? QStringLiteral(":/dark-style.qss")
                                 : QStringLiteral(":/light-style.qss"));
         qss.open(QIODevice::ReadOnly | QIODevice::Text)) {
diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp
index 24dfcd9..8481066 100644
--- a/src/core/contexts/win32windowcontext.cpp
+++ b/src/core/contexts/win32windowcontext.cpp
@@ -729,16 +729,6 @@
         }
 #endif
 
-#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
-        for (const auto attr : {
-                 _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1,
-                 _DWMWA_USE_IMMERSIVE_DARK_MODE,
-             }) {
-            const BOOL enable = TRUE;
-            DynamicApis::instance().pDwmSetWindowAttribute(hWnd, attr, &enable, sizeof(enable));
-        }
-#endif
-
         // Add managed window
         addManagedWindow(m_windowHandle, hWnd, this);
 
@@ -943,6 +933,23 @@
                 apis.pDwmExtendFrameIntoClientArea(hwnd, &defaultMargins);
             }
             return true;
+        } else if (key == QStringLiteral("dark-mode")) {
+            if (!isWin101809OrGreater()) {
+                return false;
+            }
+            BOOL enable = attribute.toBool();
+            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);
+            return true;
         }
         return false;
     }
diff --git a/src/core/qwindowkit_windows.h b/src/core/qwindowkit_windows.h
index ad691a7..5dfe712 100644
--- a/src/core/qwindowkit_windows.h
+++ b/src/core/qwindowkit_windows.h
@@ -65,6 +65,13 @@
                 rovi.dwBuildNumber >= 22000);
     }
 
+    inline bool IsWindows101809OrGreater_Real() {
+        RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
+        return (rovi.dwMajorVersion > 10) ||
+               (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 &&
+                rovi.dwBuildNumber >= 17763);
+    }
+
     inline bool IsWindows10OrGreater_Real() {
         RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
         return (rovi.dwMajorVersion > 10) ||
diff --git a/src/core/shared/qwkwindowsextra_p.h b/src/core/shared/qwkwindowsextra_p.h
index d934c07..cc6744b 100644
--- a/src/core/shared/qwkwindowsextra_p.h
+++ b/src/core/shared/qwkwindowsextra_p.h
@@ -293,6 +293,11 @@
         return result;
     }
 
+    static inline bool isWin101809OrGreater() {
+        static const bool result = IsWindows101809OrGreater_Real();
+        return result;
+    }
+
     static inline bool isWin11OrGreater() {
         static const bool result = IsWindows11OrGreater_Real();
         return result;

--
Gitblit v1.9.1