refactor: move settings to their own object

This commit is contained in:
outfoxxed 2024-03-04 01:31:31 -08:00
parent 62f99f5754
commit 4ef4cba4ee
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
8 changed files with 107 additions and 78 deletions

View file

@ -18,7 +18,40 @@
#include "qmlscreen.hpp" #include "qmlscreen.hpp"
#include "rootwrapper.hpp" #include "rootwrapper.hpp"
QuickshellSettings* QuickshellSettings::instance() {
static QuickshellSettings* instance = nullptr; // NOLINT
if (instance == nullptr) {
QJSEngine::setObjectOwnership(instance, QJSEngine::CppOwnership);
instance = new QuickshellSettings();
}
return instance;
}
void QuickshellSettings::reset() { QuickshellSettings::instance()->mWatchFiles = true; }
QString QuickshellSettings::workingDirectory() const { // NOLINT
return QDir::current().absolutePath();
}
void QuickshellSettings::setWorkingDirectory(QString workingDirectory) { // NOLINT
QDir::setCurrent(workingDirectory);
emit this->workingDirectoryChanged();
}
bool QuickshellSettings::watchFiles() const { return this->mWatchFiles; }
void QuickshellSettings::setWatchFiles(bool watchFiles) {
if (watchFiles == this->mWatchFiles) return;
this->mWatchFiles = watchFiles;
emit this->watchFilesChanged();
}
QuickshellGlobal::QuickshellGlobal(QObject* parent): QObject(parent) { QuickshellGlobal::QuickshellGlobal(QObject* parent): QObject(parent) {
// clang-format off
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::workingDirectoryChanged, this, &QuickshellGlobal::workingDirectoryChanged);
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::watchFilesChanged, this, &QuickshellGlobal::watchFilesChanged);
// clang-format on
auto* app = QCoreApplication::instance(); auto* app = QCoreApplication::instance();
auto* guiApp = qobject_cast<QGuiApplication*>(app); auto* guiApp = qobject_cast<QGuiApplication*>(app);
@ -63,6 +96,22 @@ void QuickshellGlobal::reload(bool hard) {
root->reloadGraph(hard); root->reloadGraph(hard);
} }
QString QuickshellGlobal::workingDirectory() const { // NOLINT
return QuickshellSettings::instance()->workingDirectory();
}
void QuickshellGlobal::setWorkingDirectory(QString workingDirectory) { // NOLINT
QuickshellSettings::instance()->setWorkingDirectory(std::move(workingDirectory));
}
bool QuickshellGlobal::watchFiles() const { // NOLINT
return QuickshellSettings::instance()->watchFiles();
}
void QuickshellGlobal::setWatchFiles(bool watchFiles) { // NOLINT
QuickshellSettings::instance()->setWatchFiles(watchFiles);
}
void QuickshellGlobal::updateScreens() { void QuickshellGlobal::updateScreens() {
auto screens = QGuiApplication::screens(); auto screens = QGuiApplication::screens();
this->mScreens.resize(screens.size()); this->mScreens.resize(screens.size());
@ -85,29 +134,3 @@ QVariant QuickshellGlobal::env(const QString& variable) { // NOLINT
return qEnvironmentVariable(vstr.data()); return qEnvironmentVariable(vstr.data());
} }
QString QuickshellGlobal::workingDirectory() const { // NOLINT
return QDir::current().absolutePath();
}
void QuickshellGlobal::setWorkingDirectory(const QString& workingDirectory) { // NOLINT
QDir::setCurrent(workingDirectory);
emit this->workingDirectoryChanged();
}
static QuickshellGlobal* g_instance = nullptr; // NOLINT
QuickshellGlobal* QuickshellGlobal::create(QQmlEngine* /*unused*/, QJSEngine* /*unused*/) {
return QuickshellGlobal::instance();
}
QuickshellGlobal* QuickshellGlobal::instance() {
if (g_instance == nullptr) g_instance = new QuickshellGlobal();
QJSEngine::setObjectOwnership(g_instance, QJSEngine::CppOwnership);
return g_instance;
}
void QuickshellGlobal::deleteInstance() {
delete g_instance;
g_instance = nullptr;
}

View file

@ -12,6 +12,37 @@
#include "qmlscreen.hpp" #include "qmlscreen.hpp"
///! Accessor for some options under the Quickshell type.
class QuickshellSettings: public QObject {
Q_OBJECT;
// clang-format off
/// Quickshell's working directory. Defaults to whereever quickshell was launched from.
Q_PROPERTY(QString workingDirectory READ workingDirectory WRITE setWorkingDirectory NOTIFY workingDirectoryChanged);
/// If true then the configuration will be reloaded whenever any files change.
/// Defaults to true.
Q_PROPERTY(bool watchFiles READ watchFiles WRITE setWatchFiles NOTIFY watchFilesChanged);
// clang-format on
QML_ELEMENT;
QML_UNCREATABLE("singleton");
public:
[[nodiscard]] QString workingDirectory() const;
void setWorkingDirectory(QString workingDirectory);
[[nodiscard]] bool watchFiles() const;
void setWatchFiles(bool watchFiles);
static QuickshellSettings* instance();
static void reset();
signals:
void workingDirectoryChanged();
void watchFilesChanged();
private:
bool mWatchFiles = true;
};
class QuickshellGlobal: public QObject { class QuickshellGlobal: public QObject {
Q_OBJECT; Q_OBJECT;
// clang-format off // clang-format off
@ -38,6 +69,9 @@ class QuickshellGlobal: public QObject {
Q_PROPERTY(QQmlListProperty<QuickshellScreenInfo> screens READ screens NOTIFY screensChanged); Q_PROPERTY(QQmlListProperty<QuickshellScreenInfo> screens READ screens NOTIFY screensChanged);
/// Quickshell's working directory. Defaults to whereever quickshell was launched from. /// Quickshell's working directory. Defaults to whereever quickshell was launched from.
Q_PROPERTY(QString workingDirectory READ workingDirectory WRITE setWorkingDirectory NOTIFY workingDirectoryChanged); Q_PROPERTY(QString workingDirectory READ workingDirectory WRITE setWorkingDirectory NOTIFY workingDirectoryChanged);
/// If true then the configuration will be reloaded whenever any files change.
/// Defaults to true.
Q_PROPERTY(bool watchFiles READ watchFiles WRITE setWatchFiles NOTIFY watchFilesChanged);
// clang-format on // clang-format on
QML_SINGLETON; QML_SINGLETON;
QML_NAMED_ELEMENT(Quickshell); QML_NAMED_ELEMENT(Quickshell);
@ -61,15 +95,15 @@ public:
Q_INVOKABLE QVariant env(const QString& variable); Q_INVOKABLE QVariant env(const QString& variable);
[[nodiscard]] QString workingDirectory() const; [[nodiscard]] QString workingDirectory() const;
void setWorkingDirectory(const QString& workingDirectory); void setWorkingDirectory(QString workingDirectory);
static QuickshellGlobal* create(QQmlEngine* /*unused*/, QJSEngine* /*unused*/); [[nodiscard]] bool watchFiles() const;
static QuickshellGlobal* instance(); void setWatchFiles(bool watchFiles);
static void deleteInstance();
signals: signals:
void screensChanged(); void screensChanged();
void workingDirectoryChanged(); void workingDirectoryChanged();
void watchFilesChanged();
public slots: public slots:
void updateScreens(); void updateScreens();

View file

@ -27,6 +27,10 @@ RootWrapper::RootWrapper(QString rootPath)
QObject::connect(&this->engine, &QQmlEngine::quit, app, &QCoreApplication::quit); QObject::connect(&this->engine, &QQmlEngine::quit, app, &QCoreApplication::quit);
QObject::connect(&this->engine, &QQmlEngine::exit, app, &QCoreApplication::exit); QObject::connect(&this->engine, &QQmlEngine::exit, app, &QCoreApplication::exit);
// clang-format off
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::watchFilesChanged, this, &RootWrapper::onWatchFilesChanged);
// clang-format on
this->reloadGraph(true); this->reloadGraph(true);
if (this->root == nullptr) { if (this->root == nullptr) {
@ -37,13 +41,12 @@ RootWrapper::RootWrapper(QString rootPath)
RootWrapper::~RootWrapper() { RootWrapper::~RootWrapper() {
// event loop may no longer be running so deleteLater is not an option // event loop may no longer be running so deleteLater is not an option
QuickshellGlobal::deleteInstance();
delete this->root; delete this->root;
} }
void RootWrapper::reloadGraph(bool hard) { void RootWrapper::reloadGraph(bool hard) {
if (this->root != nullptr) { if (this->root != nullptr) {
QuickshellGlobal::deleteInstance(); QuickshellSettings::reset();
this->engine.clearComponentCache(); this->engine.clearComponentCache();
} }
@ -87,25 +90,23 @@ void RootWrapper::reloadGraph(bool hard) {
QuickshellPlugin::runOnReload(); QuickshellPlugin::runOnReload();
} }
this->onConfigChanged(); this->onWatchFilesChanged();
} }
void RootWrapper::onConfigChanged() { void RootWrapper::onWatchFilesChanged() {
auto config = this->root->config(); auto watchFiles = QuickshellSettings::instance()->watchFiles();
if (config.mWatchFiles && this->configWatcher == nullptr) { if (watchFiles && this->configWatcher == nullptr) {
this->configWatcher = new FiletreeWatcher(); this->configWatcher = new FiletreeWatcher();
this->configWatcher->addPath(QFileInfo(this->rootPath).dir().path()); this->configWatcher->addPath(QFileInfo(this->rootPath).dir().path());
QObject::connect(this->root, &ShellRoot::configChanged, this, &RootWrapper::onConfigChanged);
QObject::connect( QObject::connect(
this->configWatcher, this->configWatcher,
&FiletreeWatcher::fileChanged, &FiletreeWatcher::fileChanged,
this, this,
&RootWrapper::onWatchedFilesChanged &RootWrapper::onWatchedFilesChanged
); );
} else if (!config.mWatchFiles && this->configWatcher != nullptr) { } else if (!watchFiles && this->configWatcher != nullptr) {
this->configWatcher->deleteLater(); this->configWatcher->deleteLater();
this->configWatcher = nullptr; this->configWatcher = nullptr;
} }

View file

@ -20,7 +20,7 @@ public:
void reloadGraph(bool hard); void reloadGraph(bool hard);
private slots: private slots:
void onConfigChanged(); void onWatchFilesChanged();
void onWatchedFilesChanged(); void onWatchedFilesChanged();
private: private:

View file

@ -1,16 +1,7 @@
#include "shell.hpp" #include "shell.hpp"
#include <qdir.h> #include "qmlglobal.hpp"
#include <qtmetamacros.h>
void ShellRoot::setConfig(ShellConfig config) { QuickshellSettings* ShellRoot::settings() const { // NOLINT
this->mConfig = config; return QuickshellSettings::instance();
emit this->configChanged();
}
ShellConfig ShellRoot::config() const { return this->mConfig; }
void ShellConfig::setWorkingDirectory(const QString& workingDirectory) { // NOLINT
QDir::setCurrent(workingDirectory);
} }

View file

@ -5,38 +5,17 @@
#include <qqmlengine.h> #include <qqmlengine.h>
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include "qmlglobal.hpp"
#include "reload.hpp" #include "reload.hpp"
class ShellConfig {
Q_GADGET;
Q_PROPERTY(bool watchFiles MEMBER mWatchFiles);
Q_PROPERTY(QString workingDirectory WRITE setWorkingDirectory);
public:
bool mWatchFiles = true;
void setWorkingDirectory(const QString& workingDirectory);
};
///! Root config element ///! Root config element
class ShellRoot: public ReloadPropagator { class ShellRoot: public ReloadPropagator {
Q_OBJECT; Q_OBJECT;
/// If `config.watchFiles` is true the configuration will be reloaded whenever it changes. Q_PROPERTY(QuickshellSettings* settings READ settings CONSTANT);
/// Defaults to true.
///
/// `config.workingDirectory` corrosponds to [Quickshell.workingDirectory](../quickshell#prop.workingDirectory).
Q_PROPERTY(ShellConfig config READ config WRITE setConfig NOTIFY configChanged);
QML_ELEMENT; QML_ELEMENT;
public: public:
explicit ShellRoot(QObject* parent = nullptr): ReloadPropagator(parent) {} explicit ShellRoot(QObject* parent = nullptr): ReloadPropagator(parent) {}
void setConfig(ShellConfig config); [[nodiscard]] QuickshellSettings* settings() const;
[[nodiscard]] ShellConfig config() const;
signals:
void configChanged();
private:
ShellConfig mConfig;
}; };

View file

@ -30,6 +30,7 @@ class WindowInterface: public Reloadable {
/// > Using a colored content item over a transparent window is the recommended way to work around this: /// > Using a colored content item over a transparent window is the recommended way to work around this:
/// > ```qml /// > ```qml
/// > ProxyWindow { /// > ProxyWindow {
/// > color: "transparent"
/// > Rectangle { /// > Rectangle {
/// > anchors.fill: parent /// > anchors.fill: parent
/// > color: "#20ffffff" /// > color: "#20ffffff"

View file

@ -21,8 +21,8 @@ static DisownedProcessContext* disownedCtx; // NOLINT
Process::Process(QObject* parent): QObject(parent) { Process::Process(QObject* parent): QObject(parent) {
QObject::connect( QObject::connect(
QuickshellGlobal::instance(), QuickshellSettings::instance(),
&QuickshellGlobal::workingDirectoryChanged, &QuickshellSettings::workingDirectoryChanged,
this, this,
&Process::onGlobalWorkingDirectoryChanged &Process::onGlobalWorkingDirectoryChanged
); );