From f1fb68c7210783b0200ecbf2fcb4588219646587 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Sun, 12 Apr 2026 03:58:35 +1000 Subject: [PATCH] feat: add auto save on option changes --- plugin/src/Caelestia/Config/rootconfig.cpp | 24 ++++++++++++++++++++++ plugin/src/Caelestia/Config/rootconfig.hpp | 3 +++ 2 files changed, 27 insertions(+) diff --git a/plugin/src/Caelestia/Config/rootconfig.cpp b/plugin/src/Caelestia/Config/rootconfig.cpp index 611abd57..d82d910b 100644 --- a/plugin/src/Caelestia/Config/rootconfig.cpp +++ b/plugin/src/Caelestia/Config/rootconfig.cpp @@ -96,6 +96,9 @@ void RootConfig::setupFileBackend(const QString& path, const QString& screen) { m_reloadDebounce->setInterval(50); connect(m_reloadDebounce, &QTimer::timeout, this, &RootConfig::reload); + // Auto-save when any property changes (debounced by the save timer) + connectAutoSave(this); + connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &RootConfig::onWatcherEvent); connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &RootConfig::onWatcherEvent); @@ -111,6 +114,23 @@ void RootConfig::setupFileBackend(const QString& path, const QString& screen) { }); } +void RootConfig::connectAutoSave(ConfigObject* obj) { + connect(obj, &ConfigObject::propertiesChanged, this, [this] { + if (!m_loading) + saveToFile(); + }); + + // Recurse into sub-objects + const auto* meta = obj->metaObject(); + for (int i = meta->propertyOffset(); i < meta->propertyCount(); ++i) { + auto prop = meta->property(i); + auto value = prop.read(obj); + auto* subObj = value.value(); + if (subObj) + connectAutoSave(subObj); + } +} + void RootConfig::updateWatch() { auto targetDir = QFileInfo(m_filePath).absolutePath(); @@ -192,11 +212,15 @@ std::optional RootConfig::reloadFromFile() { qCDebug(lcConfig) << "Reloading" << metaObject()->className() << "from" << m_filePath; + m_loading = true; + clearLoadedKeys(); auto jsonObj = doc.object(); loadFromJson(jsonObj); + m_loading = false; + // Collect unknown keys — caller is responsible for emitting signals m_lastUnknownKeys = collectUnknownKeys(this, jsonObj); diff --git a/plugin/src/Caelestia/Config/rootconfig.hpp b/plugin/src/Caelestia/Config/rootconfig.hpp index fb6a68b5..01ce2e54 100644 --- a/plugin/src/Caelestia/Config/rootconfig.hpp +++ b/plugin/src/Caelestia/Config/rootconfig.hpp @@ -39,10 +39,13 @@ private: void updateWatch(); void onWatcherEvent(); + void connectAutoSave(ConfigObject* obj); + QString m_filePath; QString m_screen; QString m_watchedDir; bool m_recentlySaved = false; + bool m_loading = false; QFileSystemWatcher* m_watcher = nullptr; QTimer* m_saveTimer = nullptr;