diff --git a/common/control.h b/common/control.h --- a/common/control.h +++ b/common/control.h @@ -22,6 +22,8 @@ #include #include +class QFileSystemWatcher; + class Control : public QObject { Q_OBJECT @@ -39,20 +41,26 @@ ~Control() override = default; virtual bool writeFile(); + virtual void activateWatcher(); + +Q_SIGNALS: + void changed(); protected: virtual QString dirPath() const; virtual QString filePath() const = 0; QString filePathFromHash(const QString &hash) const; void readFile(); QVariantMap& info(); const QVariantMap& constInfo() const; + QFileSystemWatcher* watcher() const; static OutputRetention convertVariantToOutputRetention(QVariant variant); private: static QString s_dirName; QVariantMap m_info; + QFileSystemWatcher *m_watcher = nullptr; }; class ControlOutput; @@ -77,6 +85,7 @@ QString filePath() const override; bool writeFile() override; + void activateWatcher() override; private: QVariantList getOutputs() const; diff --git a/common/control.cpp b/common/control.cpp --- a/common/control.cpp +++ b/common/control.cpp @@ -18,6 +18,7 @@ #include "globals.h" #include +#include #include #include @@ -31,6 +32,23 @@ { } +void Control::activateWatcher() +{ + if (m_watcher) { + return; + } + m_watcher = new QFileSystemWatcher({filePath()}, this); + connect(m_watcher, &QFileSystemWatcher::fileChanged, this, [this]() { + readFile(); + Q_EMIT changed(); + }); +} + +QFileSystemWatcher* Control::watcher() const +{ + return m_watcher; +} + bool Control::writeFile() { const QString path = filePath(); @@ -136,6 +154,18 @@ // in case of such a change while object exists? } +void ControlConfig::activateWatcher() +{ + if (watcher()) { + // Watcher was already activated. + return; + } + for (auto *output : m_outputsControls) { + output->activateWatcher(); + connect(output, &ControlOutput::changed, this, &ControlConfig::changed); + } +} + QString ControlConfig::dirPath() const { return Control::dirPath() % QStringLiteral("configs/"); diff --git a/kded/config.h b/kded/config.h --- a/kded/config.h +++ b/kded/config.h @@ -43,14 +43,18 @@ return m_data; } + void activateControlWatching(); void log(); void setValidityFlags(KScreen::Config::ValidityFlags flags) { m_validityFlags = flags; } bool canBeApplied() const; +Q_SIGNALS: + void controlChanged(); + private: friend class TestConfig; diff --git a/kded/config.cpp b/kded/config.cpp --- a/kded/config.cpp +++ b/kded/config.cpp @@ -62,6 +62,12 @@ return m_data->connectedOutputsHash(); } +void Config::activateControlWatching() +{ + connect(m_control, &ControlConfig::changed, this, &Config::controlChanged); + m_control->activateWatcher(); +} + bool Config::fileExists() const { return (QFile::exists(configsDirPath() % id()) || QFile::exists(configsDirPath() % s_fixedConfigFileName)); @@ -171,10 +177,6 @@ } const KScreen::OutputList outputs = m_data->outputs(); - // TODO: until we have the file watcher this is necessary to reload control files. - delete m_control; - m_control = new ControlConfig(m_data, this); - const auto oldConfig = readFile(); KScreen::OutputList oldOutputs; if (oldConfig) { diff --git a/kded/daemon.cpp b/kded/daemon.cpp --- a/kded/daemon.cpp +++ b/kded/daemon.cpp @@ -130,6 +130,10 @@ qCDebug(KSCREEN_KDED) << "Do set and apply specific config"; auto configWrapper = std::unique_ptr(new Config(config)); configWrapper->setValidityFlags(KScreen::Config::ValidityFlag::RequireAtLeastOneEnabledScreen); + configWrapper->activateControlWatching(); + connect(configWrapper.get(), &Config::controlChanged, this, [this]() { + // TODO + }); doApplyConfig(std::move(configWrapper)); }