forked from quickshell/quickshell
		
	refactor: move settings to their own object
This commit is contained in:
		
							parent
							
								
									62f99f5754
								
							
						
					
					
						commit
						4ef4cba4ee
					
				
					 8 changed files with 107 additions and 78 deletions
				
			
		| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ public:
 | 
			
		|||
	void reloadGraph(bool hard);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
	void onConfigChanged();
 | 
			
		||||
	void onWatchFilesChanged();
 | 
			
		||||
	void onWatchedFilesChanged();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
	);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue