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