diff --git a/src/core/paths.cpp b/src/core/paths.cpp index 57cd0f4d..689d99e4 100644 --- a/src/core/paths.cpp +++ b/src/core/paths.cpp @@ -25,10 +25,12 @@ QsPaths* QsPaths::instance() { return instance; } -void QsPaths::init(QString shellId, QString pathId) { +void QsPaths::init(QString shellId, QString pathId, QString dataOverride, QString stateOverride) { auto* instance = QsPaths::instance(); instance->shellId = std::move(shellId); instance->pathId = std::move(pathId); + instance->shellDataOverride = std::move(dataOverride); + instance->shellStateOverride = std::move(stateOverride); } QDir QsPaths::crashDir(const QString& id) { @@ -211,9 +213,16 @@ void QsPaths::linkPathDir() { QDir QsPaths::shellDataDir() { if (this->shellDataState == DirState::Unknown) { - auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); - dir = QDir(dir.filePath("by-shell")); - dir = QDir(dir.filePath(this->shellId)); + QDir dir; + if (this->shellDataOverride.isEmpty()) { + dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + dir = QDir(dir.filePath("by-shell")); + dir = QDir(dir.filePath(this->shellId)); + } else { + auto basedir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); + dir = QDir(this->shellDataOverride.replace("$BASE", basedir)); + } + this->mShellDataDir = dir; qCDebug(logPaths) << "Initialized data path:" << dir.path(); @@ -241,12 +250,24 @@ QDir QsPaths::shellStateDir() { auto home = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); dir = QDir(home.filePath(".local/state")); } -#else - auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::StateLocation)); -#endif - dir = QDir(dir.filePath("by-shell")); - dir = QDir(dir.filePath(this->shellId)); + if (this->shellStateOverride.isEmpty()) { + dir = QDir(dir.filePath("quickshell/by-shell")); + dir = QDir(dir.filePath(this->shellId)); + } else { + dir = QDir(this->shellStateOverride.replace("$BASE", dir.path())); + } +#else + QDir dir; + if (this->shellStateOverride.isEmpty()) { + dir = QDir(QStandardPaths::writableLocation(QStandardPaths::StateLocation)); + dir = QDir(dir.filePath("by-shell")); + dir = QDir(dir.filePath(this->shellId)); + } else { + auto basedir = QStandardPaths::writableLocation(QStandardPaths::GenericStateLocation); + dir = QDir(this->shellStateOverride.replace("$BASE", basedir)); + } +#endif this->mShellStateDir = dir; qCDebug(logPaths) << "Initialized state path:" << dir.path(); diff --git a/src/core/paths.hpp b/src/core/paths.hpp index d750d7f1..baaf9b25 100644 --- a/src/core/paths.hpp +++ b/src/core/paths.hpp @@ -16,7 +16,7 @@ QDataStream& operator>>(QDataStream& stream, InstanceLockInfo& info); class QsPaths { public: static QsPaths* instance(); - static void init(QString shellId, QString pathId); + static void init(QString shellId, QString pathId, QString dataOverride, QString stateOverride); static QDir crashDir(const QString& id); static QString basePath(const QString& id); static QString ipcPath(const QString& id); @@ -57,4 +57,7 @@ private: DirState shellDataState = DirState::Unknown; DirState shellStateState = DirState::Unknown; DirState shellCacheState = DirState::Unknown; + + QString shellDataOverride; + QString shellStateOverride; }; diff --git a/src/core/qmlglobal.hpp b/src/core/qmlglobal.hpp index 5ccec3b2..0290024f 100644 --- a/src/core/qmlglobal.hpp +++ b/src/core/qmlglobal.hpp @@ -111,10 +111,16 @@ class QuickshellGlobal: public QObject { /// The per-shell data directory. /// /// Usually `~/.local/share/quickshell/by-shell/` + /// + /// Can be overridden using `//@ pragma DataDir $BASE/path` in the root qml file, where `$BASE` + /// corrosponds to `$XDG_DATA_HOME` (usually `~/.local/share`). Q_PROPERTY(QString dataDir READ dataDir CONSTANT); /// The per-shell state directory. /// /// Usually `~/.local/state/quickshell/by-shell/` + /// + /// Can be overridden using `//@ pragma StateDir $BASE/path` in the root qml file, where `$BASE` + /// corrosponds to `$XDG_STATE_HOME` (usually `~/.local/state`). Q_PROPERTY(QString stateDir READ stateDir CONSTANT); /// The per-shell cache directory. /// diff --git a/src/launch/launch.cpp b/src/launch/launch.cpp index 848da499..5d265442 100644 --- a/src/launch/launch.cpp +++ b/src/launch/launch.cpp @@ -74,6 +74,8 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio bool desktopSettingsAware = true; QString iconTheme = qEnvironmentVariable("QS_ICON_THEME"); QHash envOverrides; + QString dataDir; + QString stateDir; } pragmas; auto stream = QTextStream(&file); @@ -100,6 +102,10 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio pragmas.envOverrides.insert(var, val); } else if (pragma.startsWith("ShellId ")) { shellId = pragma.sliced(8).trimmed(); + } else if (pragma.startsWith("DataDir ")) { + pragmas.dataDir = pragma.sliced(8).trimmed(); + } else if (pragma.startsWith("StateDir ")) { + pragmas.stateDir = pragma.sliced(9).trimmed(); } else { qCritical() << "Unrecognized pragma" << pragma; return -1; @@ -140,7 +146,7 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio } #endif - QsPaths::init(shellId, pathId); + QsPaths::init(shellId, pathId, pragmas.dataDir, pragmas.stateDir); QsPaths::instance()->linkRunDir(); QsPaths::instance()->linkPathDir(); LogManager::initFs();