#pragma once #include "ConfigSection.hpp" #include #include #include #include #include "Appearance.hpp" #include "Background.hpp" #include "Bar.hpp" #include "Clipboard.hpp" #include "Colors.hpp" #include "Dashboard.hpp" #include "Dock.hpp" #include "General.hpp" #include "Launcher.hpp" #include "Lock.hpp" #include "Notifs.hpp" #include "Osd.hpp" #include "Overview.hpp" #include "Screenshot.hpp" #include "Services.hpp" #include "Sidebar.hpp" #include "Utilities.hpp" class QQmlEngine; class QJSEngine; // The central hub. Exposed to QML as a singleton, so `Config.appearance. // anim.sessionGifSpeed` just works from anywhere without an import context // juggle. Every top-level JSON key is a CFG_SECTION child object; the // generic load()/save() logic lives entirely in ConfigSection, this class // only adds: the file path, the debounced/atomic write, and the QML // singleton factory. class Config : public ConfigSection { Q_OBJECT QML_ELEMENT QML_SINGLETON CFG_SECTION(Appearance, appearance, Appearance) CFG_SECTION(Background, background, Background) CFG_SECTION(Bar, bar, Bar) CFG_SECTION(Clipboard, clipboard, Clipboard) CFG_SECTION(Colors, colors, Colors) CFG_SECTION(Dashboard, dashboard, Dashboard) CFG_SECTION(Dock, dock, Dock) CFG_SECTION(General, general, General) CFG_SECTION(Launcher, launcher, Launcher) CFG_SECTION(Lock, lock, Lock) CFG_SECTION(Notifs, notifs, Notifs) CFG_SECTION(Osd, osd, Osd) CFG_SECTION(Overview, overview, Overview) CFG_SECTION(Screenshot, screenshot, Screenshot) CFG_SECTION(Services, services, Services) CFG_SECTION(Sidebar, sidebar, Sidebar) CFG_SECTION(Utilities, utilities, Utilities) public: explicit Config(QObject* parent = nullptr); static Config* create(QQmlEngine*, QJSEngine*); // Reload from disk, discarding any unsaved in-memory changes. // Synchronous for first load on startup, async for subsequent reloads. Q_INVOKABLE void load(); // Force an immediate synchronous write, bypassing the debounce timer. // Call this from your shell's shutdown handler so nothing gets lost. Q_INVOKABLE void saveNow(); // Reload from disk asynchronously (for file change notifications). Q_INVOKABLE void reloadAsync(); private Q_SLOTS: void scheduleSave(); void flushAsync(); private: QString filePath() const; void writeAtomically(const QByteArray& data); void loadSync(); void loadAsync(); QTimer m_saveTimer; bool m_loading = false; bool m_firstLoadDone = false; QFuture m_loadFuture; };