forked from quickshell/quickshell
core: support qs. imports
This commit is contained in:
parent
3d594e16dd
commit
4b35d7b51b
7 changed files with 123 additions and 35 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#include "qsintercept.hpp"
|
||||
#include <cstring>
|
||||
|
||||
#include <qdir.h>
|
||||
#include <qhash.h>
|
||||
#include <qiodevice.h>
|
||||
#include <qlogging.h>
|
||||
|
|
@ -25,27 +26,44 @@ QUrl QsUrlInterceptor::intercept(
|
|||
auto url = originalUrl;
|
||||
|
||||
if (url.scheme() == "root") {
|
||||
url.setScheme("qsintercept");
|
||||
url.setScheme("qs");
|
||||
|
||||
auto path = url.path();
|
||||
if (path.startsWith('/')) path = path.sliced(1);
|
||||
url.setPath(this->configRoot.filePath(path));
|
||||
url.setPath("@/qs/" % 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") {
|
||||
// Qt.resolvedUrl and context->resolvedUrl can use this on qml files, in which
|
||||
// case we want to keep the intercept, otherwise objects created from those paths
|
||||
// will not be able to use singletons.
|
||||
if (url.path().endsWith(".qml")) return url;
|
||||
if (url.scheme() == "qs") {
|
||||
auto path = url.path();
|
||||
|
||||
auto newUrl = url;
|
||||
newUrl.setScheme("file");
|
||||
qCDebug(logQsIntercept) << "Rewrote intercept" << url << "to" << newUrl;
|
||||
return newUrl;
|
||||
// Our import path is on "qs:@/".
|
||||
// We want to blackhole any import resolution outside of the config folder as it breaks Qt
|
||||
// but NOT file lookups that might be on "qs:/" due to a missing "file:/" prefix.
|
||||
if (path.startsWith("@/qs/")) {
|
||||
path = this->configRoot.filePath(path.sliced(5));
|
||||
} else if (!path.startsWith("/")) {
|
||||
qCDebug(logQsIntercept) << "Blackholed import URL" << url;
|
||||
return QUrl("qrc:/qs-blackhole");
|
||||
}
|
||||
|
||||
// Some types such as Image take into account where they are loading from, and force
|
||||
// asynchronous loading over a network. qs: is considered to be over a network.
|
||||
// In those cases we want to return a file:// url so asynchronous loading is not forced.
|
||||
if (type == QQmlAbstractUrlInterceptor::DataType::UrlString) {
|
||||
// Qt.resolvedUrl and context->resolvedUrl can use this on qml files, in which
|
||||
// case we want to keep the intercept, otherwise objects created from those paths
|
||||
// will not be able to use singletons.
|
||||
if (path.endsWith(".qml")) return url;
|
||||
|
||||
auto newUrl = url;
|
||||
newUrl.setScheme("file");
|
||||
// above check asserts path starts with /qs/
|
||||
newUrl.setPath(path);
|
||||
qCDebug(logQsIntercept) << "Rewrote intercept" << url << "to" << newUrl;
|
||||
return newUrl;
|
||||
}
|
||||
}
|
||||
|
||||
return url;
|
||||
|
|
@ -67,10 +85,12 @@ qint64 QsInterceptDataReply::readData(char* data, qint64 maxSize) {
|
|||
}
|
||||
|
||||
QsInterceptNetworkAccessManager::QsInterceptNetworkAccessManager(
|
||||
const QDir& configRoot,
|
||||
const QHash<QString, QString>& fileIntercepts,
|
||||
QObject* parent
|
||||
)
|
||||
: QNetworkAccessManager(parent)
|
||||
, configRoot(configRoot)
|
||||
, fileIntercepts(fileIntercepts) {}
|
||||
|
||||
QNetworkReply* QsInterceptNetworkAccessManager::createRequest(
|
||||
|
|
@ -79,19 +99,26 @@ QNetworkReply* QsInterceptNetworkAccessManager::createRequest(
|
|||
QIODevice* outgoingData
|
||||
) {
|
||||
auto url = req.url();
|
||||
if (url.scheme() == "qsintercept") {
|
||||
|
||||
if (url.scheme() == "qs") {
|
||||
auto path = url.path();
|
||||
|
||||
if (path.startsWith("@/qs/")) path = this->configRoot.filePath(path.sliced(5));
|
||||
// otherwise pass through to fs
|
||||
|
||||
qCDebug(logQsIntercept) << "Got intercept for" << path << "contains"
|
||||
<< this->fileIntercepts.value(path);
|
||||
auto data = this->fileIntercepts.value(path);
|
||||
if (data != nullptr) {
|
||||
|
||||
if (auto data = this->fileIntercepts.value(path); !data.isEmpty()) {
|
||||
return new QsInterceptDataReply(data, this);
|
||||
}
|
||||
|
||||
auto fileReq = req;
|
||||
auto fileUrl = req.url();
|
||||
fileUrl.setScheme("file");
|
||||
fileUrl.setPath(path);
|
||||
qCDebug(logQsIntercept) << "Passing through intercept" << url << "to" << fileUrl;
|
||||
|
||||
fileReq.setUrl(fileUrl);
|
||||
return this->QNetworkAccessManager::createRequest(op, fileReq, outgoingData);
|
||||
}
|
||||
|
|
@ -100,5 +127,5 @@ QNetworkReply* QsInterceptNetworkAccessManager::createRequest(
|
|||
}
|
||||
|
||||
QNetworkAccessManager* QsInterceptNetworkAccessManagerFactory::create(QObject* parent) {
|
||||
return new QsInterceptNetworkAccessManager(this->fileIntercepts, parent);
|
||||
return new QsInterceptNetworkAccessManager(this->configRoot, this->fileIntercepts, parent);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue