diff --git a/include/FramelessHelper/Core/framelessmanager.h b/include/FramelessHelper/Core/framelessmanager.h index 2954ad4..b7a015f 100644 --- a/include/FramelessHelper/Core/framelessmanager.h +++ b/include/FramelessHelper/Core/framelessmanager.h @@ -36,7 +36,7 @@ class FRAMELESSHELPER_CORE_API FramelessManager : public QObject Q_OBJECT Q_DECLARE_PRIVATE(FramelessManager) Q_DISABLE_COPY_MOVE(FramelessManager) - Q_PROPERTY(Global::SystemTheme systemTheme READ systemTheme NOTIFY systemThemeChanged FINAL) + Q_PROPERTY(Global::SystemTheme systemTheme READ systemTheme WRITE setOverrideTheme NOTIFY systemThemeChanged FINAL) Q_PROPERTY(QColor systemAccentColor READ systemAccentColor NOTIFY systemThemeChanged FINAL) Q_PROPERTY(QString wallpaper READ wallpaper NOTIFY wallpaperChanged FINAL) Q_PROPERTY(Global::WallpaperAspectStyle wallpaperAspectStyle READ wallpaperAspectStyle NOTIFY wallpaperChanged FINAL) @@ -55,6 +55,7 @@ public: public Q_SLOTS: void addWindow(const SystemParameters *params); void removeWindow(const WId windowId); + void setOverrideTheme(const Global::SystemTheme theme); Q_SIGNALS: void systemThemeChanged(); diff --git a/include/FramelessHelper/Core/private/framelessmanager_p.h b/include/FramelessHelper/Core/private/framelessmanager_p.h index 593a097..702e5e5 100644 --- a/include/FramelessHelper/Core/private/framelessmanager_p.h +++ b/include/FramelessHelper/Core/private/framelessmanager_p.h @@ -60,12 +60,16 @@ public: Q_NODISCARD static bool usePureQtImplementation(); + void setOverrideTheme(const Global::SystemTheme theme); + Q_NODISCARD bool isThemeOverrided() const; + private: void initialize(); private: FramelessManager *q_ptr = nullptr; Global::SystemTheme m_systemTheme = Global::SystemTheme::Unknown; + std::optional m_overrideTheme = std::nullopt; QColor m_accentColor = {}; #ifdef Q_OS_WINDOWS Global::DwmColorizationArea m_colorizationArea = Global::DwmColorizationArea::None; diff --git a/src/core/framelessmanager.cpp b/src/core/framelessmanager.cpp index 3f6e3c7..3852329 100644 --- a/src/core/framelessmanager.cpp +++ b/src/core/framelessmanager.cpp @@ -168,6 +168,11 @@ QFont FramelessManagerPrivate::getIconFont() SystemTheme FramelessManagerPrivate::systemTheme() const { + // The user's choice has top priority. + if (isThemeOverrided()) { + const QMutexLocker locker(&g_helper()->mutex); + return m_overrideTheme.value(); + } const QMutexLocker locker(&g_helper()->mutex); return m_systemTheme; } @@ -270,7 +275,8 @@ void FramelessManagerPrivate::notifySystemThemeHasChangedOrNot() notify = true; } #endif - if (notify) { + // Don't emit the signal if the user has overrided the global theme. + if (notify && (m_overrideTheme.value_or(SystemTheme::Unknown) == SystemTheme::Unknown)) { Q_Q(FramelessManager); Q_EMIT q->systemThemeChanged(); DEBUG.nospace() << "System theme changed. Current theme: " << m_systemTheme @@ -316,6 +322,24 @@ bool FramelessManagerPrivate::usePureQtImplementation() return result; } +void FramelessManagerPrivate::setOverrideTheme(const SystemTheme theme) +{ + const QMutexLocker locker(&g_helper()->mutex); + if (theme == SystemTheme::Unknown) { + m_overrideTheme = std::nullopt; + } else { + m_overrideTheme = theme; + } + Q_Q(FramelessManager); + Q_EMIT q->systemThemeChanged(); +} + +bool FramelessManagerPrivate::isThemeOverrided() const +{ + const QMutexLocker locker(&g_helper()->mutex); + return (m_overrideTheme.value_or(SystemTheme::Unknown) != SystemTheme::Unknown); +} + void FramelessManagerPrivate::initialize() { const QMutexLocker locker(&g_helper()->mutex); @@ -409,4 +433,10 @@ void FramelessManager::removeWindow(const WId windowId) d->removeWindow(windowId); } +void FramelessManager::setOverrideTheme(const SystemTheme theme) +{ + Q_D(FramelessManager); + d->setOverrideTheme(theme); +} + FRAMELESSHELPER_END_NAMESPACE