From 2f59395b8183b1de62bd0ba83685298d9a7e3271 Mon Sep 17 00:00:00 2001
From: Sine Striker <trueful@163.com>
Date: 摹曛, 21 12月 2023 19:56:42 +0800
Subject: [PATCH] minor tweaks

---
 src/stylesupport/styleagent_p.h       |    4 +
 src/stylesupport/styleagent_linux.cpp |    4 +
 src/stylesupport/styleagent_win.cpp   |   74 ++++++++++++++++++++++++
 src/stylesupport/styleagent_mac.mm    |    5 +
 src/stylesupport/styleagent.h         |   12 +++
 src/stylesupport/styleagent.cpp       |   22 ++++++-
 6 files changed, 116 insertions(+), 5 deletions(-)

diff --git a/src/stylesupport/styleagent.cpp b/src/stylesupport/styleagent.cpp
index d8bc9b0..d24186f 100644
--- a/src/stylesupport/styleagent.cpp
+++ b/src/stylesupport/styleagent.cpp
@@ -8,11 +8,18 @@
     StyleAgentPrivate::StyleAgentPrivate() {
     }
 
-    StyleAgentPrivate::~StyleAgentPrivate() {
-    }
+    StyleAgentPrivate::~StyleAgentPrivate() = default;
 
     void StyleAgentPrivate::init() {
-        setupSystemThemeHook();
+    }
+
+    void StyleAgentPrivate::notifyThemeChanged(StyleAgent::SystemTheme theme) {
+        if (theme == systemTheme)
+            return;
+        systemTheme = theme;
+
+        Q_Q(StyleAgent);
+        Q_EMIT q->systemThemeChanged();
     }
 
     void StyleAgentPrivate::_q_windowDestroyed() {
@@ -20,9 +27,18 @@
     }
 
     StyleAgent::StyleAgent(QObject *parent) : StyleAgent(*new StyleAgentPrivate(), parent) {
+        Q_D(StyleAgent);
+        d->setupSystemThemeHook();
     }
 
     StyleAgent::~StyleAgent() {
+        Q_D(StyleAgent);
+        d->removeSystemThemeHook();
+    }
+
+    StyleAgent::SystemTheme StyleAgent::systemTheme() const {
+        Q_D(const StyleAgent);
+        return d->systemTheme;
     }
 
     QVariant StyleAgent::windowAttribute(QWindow *window, const QString &key) const {
diff --git a/src/stylesupport/styleagent.h b/src/stylesupport/styleagent.h
index 8474820..94afa33 100644
--- a/src/stylesupport/styleagent.h
+++ b/src/stylesupport/styleagent.h
@@ -19,12 +19,22 @@
         explicit StyleAgent(QObject *parent = nullptr);
         ~StyleAgent() override;
 
+        enum SystemTheme {
+            Unknown,
+            Light,
+            Dark,
+            HighContrast,
+        };
+        Q_ENUM(SystemTheme)
+
     public:
+        SystemTheme systemTheme() const;
+
         QVariant windowAttribute(QWindow *window, const QString &key) const;
         bool setWindowAttribute(QWindow *window, const QString &key, const QVariant &attribute);
 
     Q_SIGNALS:
-        void systemThemeChanged();
+        void systemThemeChanged(); // Do we need wallpaper change notify?
 
     protected:
         StyleAgent(StyleAgentPrivate &d, QObject *parent = nullptr);
diff --git a/src/stylesupport/styleagent_linux.cpp b/src/stylesupport/styleagent_linux.cpp
index b5a6064..3c83589 100644
--- a/src/stylesupport/styleagent_linux.cpp
+++ b/src/stylesupport/styleagent_linux.cpp
@@ -7,9 +7,13 @@
     void StyleAgentPrivate::setupSystemThemeHook() {
     }
 
+    void StyleAgentPrivate::removeSystemThemeHook() {
+    }
+
     bool StyleAgentPrivate::updateWindowAttribute(QWindow *window, const QString &key,
                                                   const QVariant &attribute,
                                                   const QVariant &oldAttribute) {
+        Q_UNUSED(oldAttribute)
         return false;
     }
 
diff --git a/src/stylesupport/styleagent_mac.mm b/src/stylesupport/styleagent_mac.mm
index a4dbe86..64cdf16 100644
--- a/src/stylesupport/styleagent_mac.mm
+++ b/src/stylesupport/styleagent_mac.mm
@@ -7,9 +7,14 @@
     void StyleAgentPrivate::setupSystemThemeHook() {
     }
 
+    void StyleAgentPrivate::removeSystemThemeHook() {
+    }
+
     bool StyleAgentPrivate::updateWindowAttribute(QWindow *window, const QString &key,
                                                   const QVariant &attribute,
                                                   const QVariant &oldAttribute) {
+        Q_UNUSED(oldAttribute)
+
         if (key == QStringLiteral("no-system-buttons")) {
             if (attribute.toBool()) {
                 // TODO: set off
diff --git a/src/stylesupport/styleagent_p.h b/src/stylesupport/styleagent_p.h
index b07bc4e..b59266d 100644
--- a/src/stylesupport/styleagent_p.h
+++ b/src/stylesupport/styleagent_p.h
@@ -15,12 +15,16 @@
 
         StyleAgent *q_ptr;
 
+        StyleAgent::SystemTheme systemTheme = StyleAgent::Dark;
         QHash<QWindow *, QVariantHash> windowAttributes;
 
         virtual void setupSystemThemeHook();
+        virtual void removeSystemThemeHook();
         virtual bool updateWindowAttribute(QWindow *window, const QString &key,
                                            const QVariant &attribute, const QVariant &oldAttribute);
 
+        void notifyThemeChanged(StyleAgent::SystemTheme theme);
+
     private:
         void _q_windowDestroyed();
     };
diff --git a/src/stylesupport/styleagent_win.cpp b/src/stylesupport/styleagent_win.cpp
index 7a910d4..a685586 100644
--- a/src/stylesupport/styleagent_win.cpp
+++ b/src/stylesupport/styleagent_win.cpp
@@ -1,19 +1,91 @@
 #include "styleagent_p.h"
 
+#include <QtCore/QSet>
 #include <QtCore/QVariant>
 
 #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")) {

--
Gitblit v1.9.1