From 4f9f75cb4b70f3b76cee57d0f98b59f8475bba3b Mon Sep 17 00:00:00 2001 From: SineStriker <trueful@163.com> Date: 周三, 27 12月 2023 05:56:28 +0800 Subject: [PATCH] Add mac theme notifications --- src/core/style/styleagent_mac.mm | 81 +++++++++++++++++++++++++++ src/core/style/styleagent_win.cpp | 70 ++++++++++------------ 2 files changed, 113 insertions(+), 38 deletions(-) diff --git a/src/core/style/styleagent_mac.mm b/src/core/style/styleagent_mac.mm index 3eb3577..6c89931 100644 --- a/src/core/style/styleagent_mac.mm +++ b/src/core/style/styleagent_mac.mm @@ -1,13 +1,94 @@ #include "styleagent_p.h" +#include <Cocoa/Cocoa.h> + #include <QtCore/QVariant> namespace QWK { + static StyleAgent::SystemTheme getSystemTheme() { + NSString *osxMode = + [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; + bool isDark = [osxMode isEqualToString:@"Dark"]; + return isDark ? StyleAgent::Dark : StyleAgent::Light; + } + + static void notifyAllStyleAgents(); + +} + +// +// Objective C++ Begin +// + +@interface QWK_SystemThemeObserver : NSObject { +} +@end + +@implementation QWK_SystemThemeObserver + +- (id)init { + self = [super init]; + if (self) { + [[NSDistributedNotificationCenter defaultCenter] + addObserver:self + selector:@selector(interfaceModeChanged:) + name:@"AppleInterfaceThemeChangedNotification" + object:nil]; + } + return self; +} + +- (void)dealloc { + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + +- (void)interfaceModeChanged:(NSNotification *)notification { + QWK::notifyAllStyleAgents(); +} + +@end + +// +// Objective C++ End +// + + +namespace QWK { + + using StyleAgentSet = QSet<StyleAgentPrivate *>; + Q_GLOBAL_STATIC(StyleAgentSet, g_styleAgentSet) + + static QWK_SystemThemeObserver *g_systemThemeObserver = nil; + + void notifyAllStyleAgents() { + auto theme = getSystemTheme(); + for (auto &&ap : std::as_const(*g_styleAgentSet())) { + ap->notifyThemeChanged(theme); + } + } + void StyleAgentPrivate::setupSystemThemeHook() { + systemTheme = getSystemTheme(); + + // Alloc + if (g_styleAgentSet->isEmpty()) { + g_systemThemeObserver = [[QWK_SystemThemeObserver alloc] init]; + } + + g_styleAgentSet->insert(this); } void StyleAgentPrivate::removeSystemThemeHook() { + if (!g_styleAgentSet->remove(this)) + return; + + if (g_styleAgentSet->isEmpty()) { + // Delete + [g_systemThemeObserver release]; + g_systemThemeObserver = nil; + } } } \ No newline at end of file diff --git a/src/core/style/styleagent_win.cpp b/src/core/style/styleagent_win.cpp index 6b77012..e118713 100644 --- a/src/core/style/styleagent_win.cpp +++ b/src/core/style/styleagent_win.cpp @@ -12,6 +12,23 @@ using StyleAgentSet = QSet<StyleAgentPrivate *>; Q_GLOBAL_STATIC(StyleAgentSet, g_styleAgentSet) + static StyleAgent::SystemTheme getSystemTheme() { + if (isHighContrastModeEnabled()) { + return StyleAgent::HighContrast; + } else if (isDarkThemeActive()) { + return StyleAgent::Dark; + } else { + return StyleAgent::Light; + } + } + + static void notifyAllStyleAgents() { + auto theme = getSystemTheme(); + for (auto &&ap : std::as_const(*g_styleAgentSet())) { + ap->notifyThemeChanged(theme); + } + } + class SystemSettingEventFilter : public AppNativeEventFilter { public: bool nativeEventFilter(const QByteArray &eventType, void *message, @@ -21,42 +38,25 @@ return false; } - auto themeChanged = [message]() -> bool { - const auto msg = static_cast<const MSG *>(message); - switch (msg->message) { - case WM_THEMECHANGED: - case WM_SYSCOLORCHANGE: - case WM_DWMCOLORIZATIONCOLORCHANGED: - return true; - - case WM_SETTINGCHANGE: { - if (isImmersiveColorSetChange(msg->wParam, msg->lParam)) { - return true; - } - break; - } - - default: - break; + const auto msg = static_cast<const MSG *>(message); + switch (msg->message) { + case WM_THEMECHANGED: + case WM_SYSCOLORCHANGE: + case WM_DWMCOLORIZATIONCOLORCHANGED: { + notifyAllStyleAgents(); + break; } - return false; - }(); - if (themeChanged) { - auto theme = []() -> StyleAgent::SystemTheme { - if (isHighContrastModeEnabled()) { - return StyleAgent::HighContrast; - } else if (isDarkThemeActive()) { - return StyleAgent::Dark; - } else { - return StyleAgent::Light; + case WM_SETTINGCHANGE: { + if (isImmersiveColorSetChange(msg->wParam, msg->lParam)) { + notifyAllStyleAgents(); } - }(); - for (auto &&ap : std::as_const(*g_styleAgentSet())) { - ap->notifyThemeChanged(theme); + break; } + + default: + break; } - return false; } @@ -81,13 +81,7 @@ SystemSettingEventFilter *SystemSettingEventFilter::instance = nullptr; void StyleAgentPrivate::setupSystemThemeHook() { - if (isHighContrastModeEnabled()) { - systemTheme = StyleAgent::HighContrast; - } else if (isDarkThemeActive()) { - systemTheme = StyleAgent::Dark; - } else { - systemTheme = StyleAgent::Light; - } + systemTheme = getSystemTheme(); g_styleAgentSet->insert(this); SystemSettingEventFilter::install(); -- Gitblit v1.9.1