forked from quickshell/quickshell
core: support root:
and root:/
paths for the config root
This works everywhere urls are accepted and rewrites them from the config root as a qsintercept url.
This commit is contained in:
parent
33fac67798
commit
0519acf1d6
|
@ -27,8 +27,10 @@
|
|||
|
||||
static QHash<QQmlEngine*, EngineGeneration*> g_generations; // NOLINT
|
||||
|
||||
EngineGeneration::EngineGeneration(QmlScanner scanner)
|
||||
: scanner(std::move(scanner))
|
||||
EngineGeneration::EngineGeneration(const QDir& rootPath, QmlScanner scanner)
|
||||
: rootPath(rootPath)
|
||||
, scanner(std::move(scanner))
|
||||
, urlInterceptor(this->rootPath)
|
||||
, interceptNetFactory(this->scanner.qmldirIntercepts)
|
||||
, engine(new QQmlEngine()) {
|
||||
g_generations.insert(this->engine, this);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <qcontainerfwd.h>
|
||||
#include <qdir.h>
|
||||
#include <qfilesystemwatcher.h>
|
||||
#include <qobject.h>
|
||||
#include <qpair.h>
|
||||
|
@ -19,7 +20,7 @@ class EngineGeneration: public QObject {
|
|||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
explicit EngineGeneration(QmlScanner scanner);
|
||||
explicit EngineGeneration(const QDir& rootPath, QmlScanner scanner);
|
||||
~EngineGeneration() override;
|
||||
Q_DISABLE_COPY_MOVE(EngineGeneration);
|
||||
|
||||
|
@ -33,6 +34,7 @@ public:
|
|||
static EngineGeneration* findObjectGeneration(QObject* object);
|
||||
|
||||
RootWrapper* wrapper = nullptr;
|
||||
QDir rootPath;
|
||||
QmlScanner scanner;
|
||||
QsUrlInterceptor urlInterceptor;
|
||||
QsInterceptNetworkAccessManagerFactory interceptNetFactory;
|
||||
|
|
|
@ -16,7 +16,22 @@
|
|||
|
||||
Q_LOGGING_CATEGORY(logQsIntercept, "quickshell.interceptor", QtWarningMsg);
|
||||
|
||||
QUrl QsUrlInterceptor::intercept(const QUrl& url, QQmlAbstractUrlInterceptor::DataType type) {
|
||||
QUrl QsUrlInterceptor::intercept(
|
||||
const QUrl& originalUrl,
|
||||
QQmlAbstractUrlInterceptor::DataType type
|
||||
) {
|
||||
auto url = originalUrl;
|
||||
|
||||
if (url.scheme() == "root") {
|
||||
url.setScheme("qsintercept");
|
||||
|
||||
auto path = url.path();
|
||||
if (path.startsWith('/')) path = path.sliced(1);
|
||||
url.setPath(this->configRoot.filePath(path));
|
||||
|
||||
qCDebug(logQsIntercept) << "Rewrote root intercept" << originalUrl << "to" << url;
|
||||
}
|
||||
|
||||
// Some types such as Image take into account where they are loading from, and force
|
||||
// asynchronous loading over a network. qsintercept is considered to be over a network.
|
||||
if (type == QQmlAbstractUrlInterceptor::DataType::UrlString && url.scheme() == "qsintercept") {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <qdir.h>
|
||||
#include <qhash.h>
|
||||
#include <qloggingcategory.h>
|
||||
#include <qnetworkaccessmanager.h>
|
||||
|
@ -13,7 +14,12 @@ Q_DECLARE_LOGGING_CATEGORY(logQsIntercept);
|
|||
|
||||
class QsUrlInterceptor: public QQmlAbstractUrlInterceptor {
|
||||
public:
|
||||
QUrl intercept(const QUrl& url, QQmlAbstractUrlInterceptor::DataType type) override;
|
||||
explicit QsUrlInterceptor(const QDir& configRoot): configRoot(configRoot) {}
|
||||
|
||||
QUrl intercept(const QUrl& originalUrl, QQmlAbstractUrlInterceptor::DataType type) override;
|
||||
|
||||
private:
|
||||
QDir configRoot;
|
||||
};
|
||||
|
||||
class QsInterceptDataReply: public QNetworkReply {
|
||||
|
|
|
@ -42,10 +42,11 @@ RootWrapper::~RootWrapper() {
|
|||
}
|
||||
|
||||
void RootWrapper::reloadGraph(bool hard) {
|
||||
auto scanner = QmlScanner();
|
||||
auto rootPath = QFileInfo(this->rootPath).dir();
|
||||
auto scanner = QmlScanner(rootPath);
|
||||
scanner.scanQmlFile(this->rootPath);
|
||||
|
||||
auto* generation = new EngineGeneration(std::move(scanner));
|
||||
auto* generation = new EngineGeneration(rootPath, std::move(scanner));
|
||||
generation->wrapper = this;
|
||||
|
||||
// todo: move into EngineGeneration
|
||||
|
|
|
@ -103,7 +103,15 @@ bool QmlScanner::scanQmlFile(const QString& path) {
|
|||
this->scanDir(currentdir.path());
|
||||
|
||||
for (auto& import: imports) {
|
||||
auto ipath = currentdir.filePath(import);
|
||||
QString ipath;
|
||||
if (import.startsWith("root:")) {
|
||||
auto path = import.sliced(5);
|
||||
if (path.startsWith('/')) path = path.sliced(1);
|
||||
ipath = this->rootPath.filePath(path);
|
||||
} else {
|
||||
ipath = currentdir.filePath(import);
|
||||
}
|
||||
|
||||
auto cpath = QFileInfo(ipath).canonicalFilePath();
|
||||
|
||||
if (cpath.isEmpty()) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <qcontainerfwd.h>
|
||||
#include <qdir.h>
|
||||
#include <qhash.h>
|
||||
#include <qloggingcategory.h>
|
||||
#include <qvector.h>
|
||||
|
@ -10,6 +11,8 @@ Q_DECLARE_LOGGING_CATEGORY(logQmlScanner);
|
|||
// expects canonical paths
|
||||
class QmlScanner {
|
||||
public:
|
||||
QmlScanner(const QDir& rootPath): rootPath(rootPath) {}
|
||||
|
||||
void scanDir(const QString& path);
|
||||
// returns if the file has a singleton
|
||||
bool scanQmlFile(const QString& path);
|
||||
|
@ -17,4 +20,7 @@ public:
|
|||
QVector<QString> scannedDirs;
|
||||
QVector<QString> scannedFiles;
|
||||
QHash<QString, QString> qmldirIntercepts;
|
||||
|
||||
private:
|
||||
QDir rootPath;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue