From a5d13e19dd7f6037e10b649c49805922ae5e0fa6 Mon Sep 17 00:00:00 2001
From: SineStriker <trueful@163.com>
Date: 周五, 22 12月 2023 17:04:29 +0800
Subject: [PATCH] Prepare to remove style support again

---
 src/stylesupport/styleagent_win.cpp |  130 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 121 insertions(+), 9 deletions(-)

diff --git a/src/stylesupport/styleagent_win.cpp b/src/stylesupport/styleagent_win.cpp
index 7a910d4..67b6532 100644
--- a/src/stylesupport/styleagent_win.cpp
+++ b/src/stylesupport/styleagent_win.cpp
@@ -1,28 +1,95 @@
 #include "styleagent_p.h"
 
+#include <QtCore/QSet>
 #include <QtCore/QVariant>
+#include <QtGui/QColor>
 
 #include <QWKCore/private/qwkwindowsextra_p.h>
+#include <QWKCore/private/nativeeventfilter_p.h>
 
 namespace QWK {
 
+    using StyleAgentSet = QSet<StyleAgentPrivate *>;
+    Q_GLOBAL_STATIC(StyleAgentSet, g_styleAgentSet)
+
+    class SystemSettingEventFilter : public AppNativeEventFilter {
+    public:
+        bool nativeEventFilter(const QByteArray &eventType, void *message,
+                               QT_NATIVE_EVENT_RESULT_TYPE *result) override {
+            Q_UNUSED(eventType)
+            if (!result) {
+                return false;
+            }
+
+            const auto msg = static_cast<const MSG *>(message);
+            switch (msg->message) {
+                case WM_THEMECHANGED:
+                case WM_SYSCOLORCHANGE:
+                case WM_DWMCOLORIZATIONCOLORCHANGED: {
+                    // TODO: walk through `g_styleAgentSet`
+                    break;
+                }
+
+                case WM_SETTINGCHANGE: {
+                    if (!msg->wParam && msg->lParam &&
+                        std::wcscmp(reinterpret_cast<LPCWSTR>(msg->lParam), L"ImmersiveColorSet") ==
+                            0) {
+                        // TODO: walk through `g_styleAgentSet`
+                    }
+                    break;
+                }
+
+                default:
+                    break;
+            }
+            return false;
+        }
+
+        static SystemSettingEventFilter *instance;
+
+        static inline void install() {
+            if (instance) {
+                return;
+            }
+            instance = new SystemSettingEventFilter();
+        }
+
+        static inline void uninstall() {
+            if (!instance) {
+                return;
+            }
+            delete instance;
+            instance = nullptr;
+        }
+    };
+
+    SystemSettingEventFilter *SystemSettingEventFilter::instance = nullptr;
+
     void StyleAgentPrivate::setupSystemThemeHook() {
+        g_styleAgentSet->insert(this);
+        SystemSettingEventFilter::install();
+
+        // Initialize `systemTheme` variable
+    }
+
+    void StyleAgentPrivate::removeSystemThemeHook() {
+        if (!g_styleAgentSet->remove(this))
+            return;
+
+        if (g_styleAgentSet->isEmpty()) {
+            SystemSettingEventFilter::uninstall();
+        }
     }
 
     bool StyleAgentPrivate::updateWindowAttribute(QWindow *window, const QString &key,
                                                   const QVariant &attribute,
                                                   const QVariant &oldAttribute) {
-        const auto hwnd = reinterpret_cast<HWND>(window->winId());
+        Q_UNUSED(oldAttribute)
 
+        const auto hwnd = reinterpret_cast<HWND>(window->winId());
         const DynamicApis &apis = DynamicApis::instance();
 
-        if (key == QStringLiteral("frame-shadow")) {
-            if (attribute.toBool()) {
-                // TODO: set off
-            } else {
-                // TODO: set on
-            }
-        } else if (key == QStringLiteral("mica")) {
+        if (key == QStringLiteral("mica")) {
             if (!isWin11OrGreater()) {
                 return false;
             }
@@ -79,7 +146,10 @@
             }
             return true;
         } else if (key == QStringLiteral("acrylic-material")) {
-            if (attribute.type() == QVariant::Color) {
+            if (!isWin10OrGreater()) {
+                return false;
+            }
+            if (attribute.userType() == QMetaType::QColor) {
                 // We need to extend the window frame into the whole client area to be able
                 // to see the blurred window background.
                 static constexpr const MARGINS margins = {-1, -1, -1, -1};
@@ -123,6 +193,48 @@
                 apis.pDwmExtendFrameIntoClientArea(hwnd, &margins);
             }
             return true;
+        } else if (key == QStringLiteral("dwm-blur")) {
+            if (attribute.toBool()) {
+                // We need to extend the window frame into the whole client area to be able
+                // to see the blurred window background.
+                static constexpr const MARGINS margins = {-1, -1, -1, -1};
+                apis.pDwmExtendFrameIntoClientArea(hwnd, &margins);
+                if (isWin8OrGreater()) {
+                    ACCENT_POLICY policy{};
+                    policy.dwAccentState = ACCENT_ENABLE_BLURBEHIND;
+                    policy.dwAccentFlags = ACCENT_NONE;
+                    WINDOWCOMPOSITIONATTRIBDATA wcad{};
+                    wcad.Attrib = WCA_ACCENT_POLICY;
+                    wcad.pvData = &policy;
+                    wcad.cbData = sizeof(policy);
+                    apis.pSetWindowCompositionAttribute(hwnd, &wcad);
+                } else {
+                    DWM_BLURBEHIND bb{};
+                    bb.fEnable = TRUE;
+                    bb.fTransitionOnMaximized = TRUE;
+                    bb.dwFlags = DWM_BB_ENABLE | DWM_BB_TRANSITIONONMAXIMIZED;
+                    apis.pDwmEnableBlurBehindWindow(hwnd, &bb);
+                }
+            } else {
+                if (isWin8OrGreater()) {
+                    ACCENT_POLICY policy{};
+                    policy.dwAccentState = ACCENT_DISABLED;
+                    policy.dwAccentFlags = ACCENT_NONE;
+                    WINDOWCOMPOSITIONATTRIBDATA wcad{};
+                    wcad.Attrib = WCA_ACCENT_POLICY;
+                    wcad.pvData = &policy;
+                    wcad.cbData = sizeof(policy);
+                    apis.pSetWindowCompositionAttribute(hwnd, &wcad);
+                } else {
+                    DWM_BLURBEHIND bb{};
+                    bb.fEnable = FALSE;
+                    bb.dwFlags = DWM_BB_ENABLE;
+                    apis.pDwmEnableBlurBehindWindow(hwnd, &bb);
+                }
+                static constexpr const MARGINS margins = {0, 0, 0, 0};
+                apis.pDwmExtendFrameIntoClientArea(hwnd, &margins);
+            }
+            return true;
         }
         return false;
     }

--
Gitblit v1.9.1