From 1385ca15debbb4ae964cfa2d42fb70bddaea6305 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Sun, 12 Apr 2026 22:16:32 +1000 Subject: [PATCH] feat: add warning on global options using per-mon confs --- plugin/src/Caelestia/Config/configobject.cpp | 8 +++++ plugin/src/Caelestia/Config/configobject.hpp | 32 +++++++++++++++++++ plugin/src/Caelestia/Config/generalconfig.hpp | 20 ++++++------ .../src/Caelestia/Config/launcherconfig.hpp | 24 +++++++------- plugin/src/Caelestia/Config/notifsconfig.hpp | 8 ++--- plugin/src/Caelestia/Config/serviceconfig.hpp | 28 ++++++++-------- plugin/src/Caelestia/Config/userpaths.hpp | 4 +-- .../src/Caelestia/Config/utilitiesconfig.hpp | 28 ++++++++-------- 8 files changed, 96 insertions(+), 56 deletions(-) diff --git a/plugin/src/Caelestia/Config/configobject.cpp b/plugin/src/Caelestia/Config/configobject.cpp index cc38d7e5..d4a1a77f 100644 --- a/plugin/src/Caelestia/Config/configobject.cpp +++ b/plugin/src/Caelestia/Config/configobject.cpp @@ -29,6 +29,10 @@ void ConfigObject::loadFromJson(const QJsonObject& obj) { if (!obj.contains(key)) continue; + if (m_global && m_globalOnlyKeys.contains(key)) + qCWarning( + lcConfig, "Option '%s' is global-only and will be ignored in per-monitor config", qUtf8Printable(key)); + const auto jsonVal = obj.value(key); // Recurse into sub-objects @@ -227,6 +231,10 @@ void ConfigObject::onGlobalPropertiesChanged(const QMap& chan } } +void ConfigObject::markGlobalOnly(const QString& name) { + m_globalOnlyKeys.insert(name); +} + void ConfigObject::notifyPropertyChanged(const QString& name, const QVariant& value) { m_pendingChanges.insert(name, value); diff --git a/plugin/src/Caelestia/Config/configobject.hpp b/plugin/src/Caelestia/Config/configobject.hpp index 4e0cae92..8e3969a4 100644 --- a/plugin/src/Caelestia/Config/configobject.hpp +++ b/plugin/src/Caelestia/Config/configobject.hpp @@ -41,6 +41,34 @@ public: private: \ Type* m_##name = nullptr; +// Like CONFIG_PROPERTY but warns on read/write when accessed on a per-monitor overlay. +#define CONFIG_GLOBAL_PROPERTY(Type, name, ...) \ + Q_PROPERTY(Type name READ name WRITE set_##name NOTIFY name##Changed) \ + \ +public: \ + [[nodiscard]] Type name() const { \ + if (isOverlay()) \ + qCWarning(caelestia::config::lcConfig, "Reading global-only option '%s' on per-monitor overlay", #name); \ + return m_##name; \ + } \ + void set_##name(const Type& val) { \ + if (isOverlay()) \ + qCWarning(caelestia::config::lcConfig, "Writing global-only option '%s' on per-monitor overlay", #name); \ + if (caelestia::config::ConfigObject::updateMember(m_##name, val)) { \ + markPropertyLoaded(QStringLiteral(#name)); \ + Q_EMIT name##Changed(); \ + notifyPropertyChanged(QStringLiteral(#name), QVariant::fromValue(m_##name)); \ + } \ + } \ + Q_SIGNAL void name##Changed(); \ + \ +private: \ + Type m_##name __VA_OPT__(= __VA_ARGS__); \ + const bool m_##name##_go = [this] { \ + markGlobalOnly(QStringLiteral(#name)); \ + return true; \ + }(); + namespace caelestia::config { Q_DECLARE_LOGGING_CATEGORY(lcConfig) @@ -61,6 +89,8 @@ public: [[nodiscard]] bool isPropertyLoaded(const QString& name) const { return m_loadedKeys.contains(name); } + [[nodiscard]] bool isOverlay() const { return m_global != nullptr; } + Q_INVOKABLE void resetOption(const QString& name); template static bool updateMember(T& member, const T& value) { @@ -80,6 +110,7 @@ signals: protected: void markPropertyLoaded(const QString& name); + void markGlobalOnly(const QString& name); void notifyPropertyChanged(const QString& name, const QVariant& value); private: @@ -89,6 +120,7 @@ private: // Per-monitor overlay state ConfigObject* m_global = nullptr; QSet m_loadedKeys; + QSet m_globalOnlyKeys; QMap m_pendingChanges; QTimer* m_batchTimer = nullptr; }; diff --git a/plugin/src/Caelestia/Config/generalconfig.hpp b/plugin/src/Caelestia/Config/generalconfig.hpp index 32b7df1e..f84cfa34 100644 --- a/plugin/src/Caelestia/Config/generalconfig.hpp +++ b/plugin/src/Caelestia/Config/generalconfig.hpp @@ -12,10 +12,10 @@ class GeneralApps : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_PROPERTY(QStringList, terminal, { QStringLiteral("foot") }) - CONFIG_PROPERTY(QStringList, audio, { QStringLiteral("pavucontrol") }) - CONFIG_PROPERTY(QStringList, playback, { QStringLiteral("mpv") }) - CONFIG_PROPERTY(QStringList, explorer, { QStringLiteral("thunar") }) + CONFIG_GLOBAL_PROPERTY(QStringList, terminal, { QStringLiteral("foot") }) + CONFIG_GLOBAL_PROPERTY(QStringList, audio, { QStringLiteral("pavucontrol") }) + CONFIG_GLOBAL_PROPERTY(QStringList, playback, { QStringLiteral("mpv") }) + CONFIG_GLOBAL_PROPERTY(QStringList, explorer, { QStringLiteral("thunar") }) public: explicit GeneralApps(QObject* parent = nullptr) @@ -26,9 +26,9 @@ class GeneralIdle : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_PROPERTY(bool, lockBeforeSleep, true) - CONFIG_PROPERTY(bool, inhibitWhenAudio, true) - CONFIG_PROPERTY(QVariantList, timeouts) + CONFIG_GLOBAL_PROPERTY(bool, lockBeforeSleep, true) + CONFIG_GLOBAL_PROPERTY(bool, inhibitWhenAudio, true) + CONFIG_GLOBAL_PROPERTY(QVariantList, timeouts) public: explicit GeneralIdle(QObject* parent = nullptr) @@ -39,8 +39,8 @@ class GeneralBattery : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_PROPERTY(QVariantList, warnLevels) - CONFIG_PROPERTY(int, criticalLevel, 3) + CONFIG_GLOBAL_PROPERTY(QVariantList, warnLevels) + CONFIG_GLOBAL_PROPERTY(int, criticalLevel, 3) public: explicit GeneralBattery(QObject* parent = nullptr) @@ -51,7 +51,7 @@ class GeneralConfig : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_PROPERTY(QString, logo) + CONFIG_GLOBAL_PROPERTY(QString, logo) CONFIG_PROPERTY(qreal, mediaGifSpeedAdjustment, 300) CONFIG_PROPERTY(qreal, sessionGifSpeed, 0.7) CONFIG_SUBOBJECT(GeneralApps, apps) diff --git a/plugin/src/Caelestia/Config/launcherconfig.hpp b/plugin/src/Caelestia/Config/launcherconfig.hpp index 23f71734..b0c8d06b 100644 --- a/plugin/src/Caelestia/Config/launcherconfig.hpp +++ b/plugin/src/Caelestia/Config/launcherconfig.hpp @@ -12,11 +12,11 @@ class LauncherUseFuzzy : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_PROPERTY(bool, apps, false) - CONFIG_PROPERTY(bool, actions, false) - CONFIG_PROPERTY(bool, schemes, false) - CONFIG_PROPERTY(bool, variants, false) - CONFIG_PROPERTY(bool, wallpapers, false) + CONFIG_GLOBAL_PROPERTY(bool, apps, false) + CONFIG_GLOBAL_PROPERTY(bool, actions, false) + CONFIG_GLOBAL_PROPERTY(bool, schemes, false) + CONFIG_GLOBAL_PROPERTY(bool, variants, false) + CONFIG_GLOBAL_PROPERTY(bool, wallpapers, false) public: explicit LauncherUseFuzzy(QObject* parent = nullptr) @@ -31,15 +31,15 @@ class LauncherConfig : public ConfigObject { CONFIG_PROPERTY(bool, showOnHover, false) CONFIG_PROPERTY(int, maxShown, 7) CONFIG_PROPERTY(int, maxWallpapers, 9) - CONFIG_PROPERTY(QString, specialPrefix, QStringLiteral("@")) - CONFIG_PROPERTY(QString, actionPrefix, QStringLiteral(">")) - CONFIG_PROPERTY(bool, enableDangerousActions, false) + CONFIG_GLOBAL_PROPERTY(QString, specialPrefix, QStringLiteral("@")) + CONFIG_GLOBAL_PROPERTY(QString, actionPrefix, QStringLiteral(">")) + CONFIG_GLOBAL_PROPERTY(bool, enableDangerousActions, false) CONFIG_PROPERTY(int, dragThreshold, 50) - CONFIG_PROPERTY(bool, vimKeybinds, false) - CONFIG_PROPERTY(QStringList, favouriteApps) - CONFIG_PROPERTY(QStringList, hiddenApps) + CONFIG_GLOBAL_PROPERTY(bool, vimKeybinds, false) + CONFIG_GLOBAL_PROPERTY(QStringList, favouriteApps) + CONFIG_GLOBAL_PROPERTY(QStringList, hiddenApps) CONFIG_SUBOBJECT(LauncherUseFuzzy, useFuzzy) - CONFIG_PROPERTY(QVariantList, actions) + CONFIG_GLOBAL_PROPERTY(QVariantList, actions) public: explicit LauncherConfig(QObject* parent = nullptr) diff --git a/plugin/src/Caelestia/Config/notifsconfig.hpp b/plugin/src/Caelestia/Config/notifsconfig.hpp index 745b057b..eef360fe 100644 --- a/plugin/src/Caelestia/Config/notifsconfig.hpp +++ b/plugin/src/Caelestia/Config/notifsconfig.hpp @@ -10,12 +10,12 @@ class NotifsConfig : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_PROPERTY(bool, expire, true) - CONFIG_PROPERTY(QString, fullscreen, QStringLiteral("on")) - CONFIG_PROPERTY(int, defaultExpireTimeout, 5000) + CONFIG_GLOBAL_PROPERTY(bool, expire, true) + CONFIG_GLOBAL_PROPERTY(QString, fullscreen, QStringLiteral("on")) + CONFIG_GLOBAL_PROPERTY(int, defaultExpireTimeout, 5000) CONFIG_PROPERTY(qreal, clearThreshold, 0.3) CONFIG_PROPERTY(int, expandThreshold, 20) - CONFIG_PROPERTY(bool, actionOnClick, false) + CONFIG_GLOBAL_PROPERTY(bool, actionOnClick, false) CONFIG_PROPERTY(int, groupPreviewNum, 3) CONFIG_PROPERTY(bool, openExpanded, false) diff --git a/plugin/src/Caelestia/Config/serviceconfig.hpp b/plugin/src/Caelestia/Config/serviceconfig.hpp index 062bf451..439092af 100644 --- a/plugin/src/Caelestia/Config/serviceconfig.hpp +++ b/plugin/src/Caelestia/Config/serviceconfig.hpp @@ -11,20 +11,20 @@ class ServiceConfig : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_PROPERTY(QString, weatherLocation) - CONFIG_PROPERTY(bool, useFahrenheit, false) - CONFIG_PROPERTY(bool, useFahrenheitPerformance, false) - CONFIG_PROPERTY(bool, useTwelveHourClock, false) - CONFIG_PROPERTY(QString, gpuType) - CONFIG_PROPERTY(int, visualiserBars, 45) - CONFIG_PROPERTY(qreal, audioIncrement, 0.1) - CONFIG_PROPERTY(qreal, brightnessIncrement, 0.1) - CONFIG_PROPERTY(qreal, maxVolume, 1.0) - CONFIG_PROPERTY(bool, smartScheme, true) - CONFIG_PROPERTY(QString, defaultPlayer, QStringLiteral("Spotify")) - CONFIG_PROPERTY(QVariantList, playerAliases) - CONFIG_PROPERTY(bool, showLyrics, false) - CONFIG_PROPERTY(QString, lyricsBackend, QStringLiteral("Auto")) + CONFIG_GLOBAL_PROPERTY(QString, weatherLocation) + CONFIG_GLOBAL_PROPERTY(bool, useFahrenheit, false) + CONFIG_GLOBAL_PROPERTY(bool, useFahrenheitPerformance, false) + CONFIG_GLOBAL_PROPERTY(bool, useTwelveHourClock, false) + CONFIG_GLOBAL_PROPERTY(QString, gpuType) + CONFIG_GLOBAL_PROPERTY(int, visualiserBars, 45) + CONFIG_GLOBAL_PROPERTY(qreal, audioIncrement, 0.1) + CONFIG_GLOBAL_PROPERTY(qreal, brightnessIncrement, 0.1) + CONFIG_GLOBAL_PROPERTY(qreal, maxVolume, 1.0) + CONFIG_GLOBAL_PROPERTY(bool, smartScheme, true) + CONFIG_GLOBAL_PROPERTY(QString, defaultPlayer, QStringLiteral("Spotify")) + CONFIG_GLOBAL_PROPERTY(QVariantList, playerAliases) + CONFIG_GLOBAL_PROPERTY(bool, showLyrics, false) + CONFIG_GLOBAL_PROPERTY(QString, lyricsBackend, QStringLiteral("Auto")) public: explicit ServiceConfig(QObject* parent = nullptr) diff --git a/plugin/src/Caelestia/Config/userpaths.hpp b/plugin/src/Caelestia/Config/userpaths.hpp index 18812188..f0d0fb2e 100644 --- a/plugin/src/Caelestia/Config/userpaths.hpp +++ b/plugin/src/Caelestia/Config/userpaths.hpp @@ -12,9 +12,9 @@ class UserPaths : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_PROPERTY(QString, wallpaperDir, + CONFIG_GLOBAL_PROPERTY(QString, wallpaperDir, QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + QStringLiteral("/Wallpapers")) - CONFIG_PROPERTY(QString, lyricsDir, QDir::homePath() + QStringLiteral("/Music/lyrics/")) + CONFIG_GLOBAL_PROPERTY(QString, lyricsDir, QDir::homePath() + QStringLiteral("/Music/lyrics/")) CONFIG_PROPERTY(QString, sessionGif, QStringLiteral("root:/assets/kurukuru.gif")) CONFIG_PROPERTY(QString, mediaGif, QStringLiteral("root:/assets/bongocat.gif")) CONFIG_PROPERTY(QString, noNotifsPic, QStringLiteral("root:/assets/dino.png")) diff --git a/plugin/src/Caelestia/Config/utilitiesconfig.hpp b/plugin/src/Caelestia/Config/utilitiesconfig.hpp index 57b6fccd..cabb877e 100644 --- a/plugin/src/Caelestia/Config/utilitiesconfig.hpp +++ b/plugin/src/Caelestia/Config/utilitiesconfig.hpp @@ -11,19 +11,19 @@ class UtilitiesToasts : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_PROPERTY(bool, configLoaded, true) CONFIG_PROPERTY(QString, fullscreen, QStringLiteral("off")) - CONFIG_PROPERTY(bool, chargingChanged, true) - CONFIG_PROPERTY(bool, gameModeChanged, true) - CONFIG_PROPERTY(bool, dndChanged, true) - CONFIG_PROPERTY(bool, audioOutputChanged, true) - CONFIG_PROPERTY(bool, audioInputChanged, true) - CONFIG_PROPERTY(bool, capsLockChanged, true) - CONFIG_PROPERTY(bool, numLockChanged, true) - CONFIG_PROPERTY(bool, kbLayoutChanged, true) - CONFIG_PROPERTY(bool, kbLimit, true) - CONFIG_PROPERTY(bool, vpnChanged, true) - CONFIG_PROPERTY(bool, nowPlaying, false) + CONFIG_GLOBAL_PROPERTY(bool, configLoaded, true) + CONFIG_GLOBAL_PROPERTY(bool, chargingChanged, true) + CONFIG_GLOBAL_PROPERTY(bool, gameModeChanged, true) + CONFIG_GLOBAL_PROPERTY(bool, dndChanged, true) + CONFIG_GLOBAL_PROPERTY(bool, audioOutputChanged, true) + CONFIG_GLOBAL_PROPERTY(bool, audioInputChanged, true) + CONFIG_GLOBAL_PROPERTY(bool, capsLockChanged, true) + CONFIG_GLOBAL_PROPERTY(bool, numLockChanged, true) + CONFIG_GLOBAL_PROPERTY(bool, kbLayoutChanged, true) + CONFIG_GLOBAL_PROPERTY(bool, kbLimit, true) + CONFIG_GLOBAL_PROPERTY(bool, vpnChanged, true) + CONFIG_GLOBAL_PROPERTY(bool, nowPlaying, false) public: explicit UtilitiesToasts(QObject* parent = nullptr) @@ -34,8 +34,8 @@ class UtilitiesVpn : public ConfigObject { Q_OBJECT QML_ANONYMOUS - CONFIG_PROPERTY(bool, enabled, false) - CONFIG_PROPERTY(QVariantList, provider) + CONFIG_GLOBAL_PROPERTY(bool, enabled, false) + CONFIG_GLOBAL_PROPERTY(QVariantList, provider) public: explicit UtilitiesVpn(QObject* parent = nullptr)