// Copyright (C) 2023-2024 Stdware Collections // SPDX-License-Identifier: Apache-2.0 #include "styleagent_p.h" #include #include #include #include #include namespace QWK { using StyleAgentSet = QSet; 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, QT_NATIVE_EVENT_RESULT_TYPE *result) override { Q_UNUSED(eventType) if (!result) { return false; } const auto msg = static_cast(message); switch (msg->message) { case WM_THEMECHANGED: case WM_SYSCOLORCHANGE: case WM_DWMCOLORIZATIONCOLORCHANGED: { notifyAllStyleAgents(); break; } case WM_SETTINGCHANGE: { if (isImmersiveColorSetChange(msg->wParam, msg->lParam)) { notifyAllStyleAgents(); } 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() { systemTheme = getSystemTheme(); g_styleAgentSet->insert(this); SystemSettingEventFilter::install(); } void StyleAgentPrivate::removeSystemThemeHook() { if (!g_styleAgentSet->remove(this)) return; if (g_styleAgentSet->isEmpty()) { SystemSettingEventFilter::uninstall(); } } }