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
					
				
					 7 changed files with 48 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue