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 "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) {
// 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* guiApp = qobject_cast<QGuiApplication*>(app);
@ -63,6 +96,22 @@ void QuickshellGlobal::reload(bool 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() {
auto screens = QGuiApplication::screens();
this->mScreens.resize(screens.size());
@ -85,29 +134,3 @@ QVariant QuickshellGlobal::env(const QString& variable) { // NOLINT
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"
///! 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 {
Q_OBJECT;
// clang-format off
@ -38,6 +69,9 @@ class QuickshellGlobal: public QObject {
Q_PROPERTY(QQmlListProperty<QuickshellScreenInfo> screens READ screens NOTIFY screensChanged);
/// 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_SINGLETON;
QML_NAMED_ELEMENT(Quickshell);
@ -61,15 +95,15 @@ public:
Q_INVOKABLE QVariant env(const QString& variable);
[[nodiscard]] QString workingDirectory() const;
void setWorkingDirectory(const QString& workingDirectory);
void setWorkingDirectory(QString workingDirectory);
static QuickshellGlobal* create(QQmlEngine* /*unused*/, QJSEngine* /*unused*/);
static QuickshellGlobal* instance();
static void deleteInstance();
[[nodiscard]] bool watchFiles() const;
void setWatchFiles(bool watchFiles);
signals:
void screensChanged();
void workingDirectoryChanged();
void watchFilesChanged();
public slots:
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::exit, app, &QCoreApplication::exit);
// clang-format off
QObject::connect(QuickshellSettings::instance(), &QuickshellSettings::watchFilesChanged, this, &RootWrapper::onWatchFilesChanged);
// clang-format on
this->reloadGraph(true);
if (this->root == nullptr) {
@ -37,13 +41,12 @@ RootWrapper::RootWrapper(QString rootPath)
RootWrapper::~RootWrapper() {
// event loop may no longer be running so deleteLater is not an option
QuickshellGlobal::deleteInstance();
delete this->root;
}
void RootWrapper::reloadGraph(bool hard) {
if (this->root != nullptr) {
QuickshellGlobal::deleteInstance();
QuickshellSettings::reset();
this->engine.clearComponentCache();
}
@ -87,25 +90,23 @@ void RootWrapper::reloadGraph(bool hard) {
QuickshellPlugin::runOnReload();
}
this->onConfigChanged();
this->onWatchFilesChanged();
}
void RootWrapper::onConfigChanged() {
auto config = this->root->config();
void RootWrapper::onWatchFilesChanged() {
auto watchFiles = QuickshellSettings::instance()->watchFiles();
if (config.mWatchFiles && this->configWatcher == nullptr) {
if (watchFiles && this->configWatcher == nullptr) {
this->configWatcher = new FiletreeWatcher();
this->configWatcher->addPath(QFileInfo(this->rootPath).dir().path());
QObject::connect(this->root, &ShellRoot::configChanged, this, &RootWrapper::onConfigChanged);
QObject::connect(
this->configWatcher,
&FiletreeWatcher::fileChanged,
this,
&RootWrapper::onWatchedFilesChanged
);
} else if (!config.mWatchFiles && this->configWatcher != nullptr) {
} else if (!watchFiles && this->configWatcher != nullptr) {
this->configWatcher->deleteLater();
this->configWatcher = nullptr;
}

View file

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

View file

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

View file

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

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:
/// > ```qml
/// > ProxyWindow {
/// > color: "transparent"
/// > Rectangle {
/// > anchors.fill: parent
/// > color: "#20ffffff"

View file

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