From 5fcf959788954043d769928080beedca8ded894b Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sat, 10 Oct 2026 03:14:07 -0700 Subject: [PATCH] Patch Quickshell to temporarily work around Qt 6.12 breakage (#935) Namespacing conflict from new Qt 6.12 types, patching until its clear if this is a Qt bug or not. --- pkgbuilds/quickshell/PKGBUILD | 9 +- pkgbuilds/quickshell/load_qtquick_611.patch | 203 ++++++++++++++++++++ 2 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 pkgbuilds/quickshell/load_qtquick_611.patch diff --git a/pkgbuilds/quickshell/PKGBUILD b/pkgbuilds/quickshell/PKGBUILD index 31b830fc..eefb61f4 100644 --- a/pkgbuilds/quickshell/PKGBUILD +++ b/pkgbuilds/quickshell/PKGBUILD @@ -1,6 +1,6 @@ pkgname=quickshell pkgver=0.3.2 -pkgrel=2 +pkgrel=3 pkgdesc='Flexible toolkit for making desktop shells with QtQuick' arch=(x86_64 aarch64) url='https://github.com/quickshell-mirror/quickshell' @@ -38,10 +38,17 @@ provides=("$pkgname") conflicts=(quickshell-git) _archive="$pkgname-$pkgver" source=("$_archive.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz" + load_qtquick_611.patch quickshell-check.hook) sha256sums=('946a27e2a276917a03c1079e5c60971af84ece73088c3661dee455d92eb420f7' + '23b65d205d825f11a1cd8501acbc6e50250d09a6ce607e2ff8b3cf5d438bd0ce' '8543e21aeaaa5441b73a679160e7601a957f16c433e8d6bd9257e80bd0e94083') +prepare() { + cd "$_archive" + patch -Np1 --fuzz=0 -i "$srcdir/load_qtquick_611.patch" +} + build() { cd "$_archive" cmake -G Ninja -B build -W no-dev \ diff --git a/pkgbuilds/quickshell/load_qtquick_611.patch b/pkgbuilds/quickshell/load_qtquick_611.patch new file mode 100644 index 00000000..660965b4 --- /dev/null +++ b/pkgbuilds/quickshell/load_qtquick_611.patch @@ -0,0 +1,203 @@ +diff --git c/src/core/generation.cpp i/src/core/generation.cpp +index ad5dca2..878abbc 100644 +--- c/src/core/generation.cpp ++++ i/src/core/generation.cpp +@@ -38,7 +38,7 @@ static QHash g_generations; // NOLINT + EngineGeneration::EngineGeneration(const QDir& rootPath, QmlScanner scanner) + : rootPath(rootPath) + , scanner(std::move(scanner)) +- , urlInterceptor(this->rootPath) ++ , urlInterceptor(this->rootPath, this->scanner) + , interceptNetFactory(this->rootPath, this->scanner.fileIntercepts) + , engine(new QQmlEngine()) { + g_generations.insert(this->engine, this); +diff --git c/src/core/qsintercept.cpp i/src/core/qsintercept.cpp +index 6687681..8f14178 100644 +--- c/src/core/qsintercept.cpp ++++ i/src/core/qsintercept.cpp +@@ -2,6 +2,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -16,6 +17,7 @@ + #include + + #include "logcat.hpp" ++#include "scan.hpp" + + QS_LOGGING_CATEGORY(logQsIntercept, "quickshell.interceptor", QtWarningMsg); + +@@ -24,6 +26,13 @@ QUrl QsUrlInterceptor::intercept( + QQmlAbstractUrlInterceptor::DataType type + ) { + auto url = originalUrl; ++ if (this->scanner.omarchyLoadPatch && type == QQmlAbstractUrlInterceptor::DataType::QmlFile ++ && url.isLocalFile()) ++ { ++ auto path = QFileInfo(url.toLocalFile()).absoluteFilePath(); ++ this->scanner.scanDir(QFileInfo(path).dir()); ++ if (this->scanner.fileIntercepts.contains(path)) url.setScheme("qs"); ++ } + + if (url.scheme() == "root") { + url.setScheme("qs"); +diff --git c/src/core/qsintercept.hpp i/src/core/qsintercept.hpp +index c3d8b55..ccfd651 100644 +--- c/src/core/qsintercept.hpp ++++ i/src/core/qsintercept.hpp +@@ -14,14 +14,19 @@ + + QS_DECLARE_LOGGING_CATEGORY(logQsIntercept); + ++class QmlScanner; ++ + class QsUrlInterceptor: public QQmlAbstractUrlInterceptor { + public: +- explicit QsUrlInterceptor(const QDir& configRoot): configRoot(configRoot) {} ++ QsUrlInterceptor(const QDir& configRoot, QmlScanner& scanner) ++ : configRoot(configRoot) ++ , scanner(scanner) {} + + QUrl intercept(const QUrl& originalUrl, QQmlAbstractUrlInterceptor::DataType type) override; + + private: + QDir configRoot; ++ QmlScanner& scanner; + }; + + class QsInterceptDataReply: public QNetworkReply { +diff --git c/src/core/scan.cpp i/src/core/scan.cpp +index 9f33302..de443ba 100644 +--- c/src/core/scan.cpp ++++ i/src/core/scan.cpp +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -22,6 +23,12 @@ + + QS_LOGGING_CATEGORY(logQmlScanner, "quickshell.qmlscanner", QtWarningMsg); + ++namespace { ++const auto unversionedQtQuickImport = QRegularExpression( ++ QStringLiteral(R"(^([ \t]*import[ \t]+QtQuick)(?=[ \t]*(?:as[ \t]|;|//|/\*|$)))") ++); ++} // namespace ++ + bool QmlScanner::readAndHashFile(const QString& path, QByteArray& data) { + auto file = QFile(path); + if (!file.open(QFile::ReadOnly)) return false; +@@ -65,13 +72,19 @@ void QmlScanner::scanDir(const QDir& dir) { + ) << "Found qmldir file, qmldir synthesization will be disabled for directory" + << path; + seenQmldir = true; +- } else if (name.at(0).isUpper() && name.endsWith(".qml")) { +- auto& entry = entries.emplaceBack(); ++ } else if (name.endsWith(".qml") && (this->omarchyLoadPatch || name.at(0).isUpper())) { ++ if (name.at(0).isUpper()) { ++ auto& entry = entries.emplaceBack(); + +- if (this->scanQmlFile(dir.filePath(name), entry.singleton, entry.internal)) { +- entry.name = name; ++ if (this->scanQmlFile(dir.filePath(name), entry.singleton, entry.internal)) { ++ entry.name = name; ++ } else { ++ entries.pop_back(); ++ } + } else { +- entries.pop_back(); ++ bool singleton = false; ++ bool internal = false; ++ this->scanQmlFile(dir.filePath(name), singleton, internal); + } + } else if (name.at(0).isUpper() && name.endsWith(".qml.json")) { + if (this->scanQmlJson(dir.filePath(name))) { +@@ -121,9 +134,10 @@ void QmlScanner::scanDir(const QDir& dir) { + qCDebug(logQmlScanner) << "Synthesized qmldir for" << path << qPrintable("\n" + qmldir); + this->fileIntercepts.insert(QDir(path).filePath("qmldir"), qmldir); + } ++ + } + +-bool QmlScanner::scanQmlFile(const QString& path, bool& singleton, bool& internal) { ++bool QmlScanner::scanQmlFile(const QString& path, bool& singleton, bool& internal, bool isRoot) { + if (this->scannedFiles.contains(path)) return false; + this->scannedFiles.push_back(path); + +@@ -159,6 +173,9 @@ bool QmlScanner::scanQmlFile(const QString& path, bool& singleton, bool& interna + if (!sourceMasked && inHeader) { + if (!singleton && line == "pragma Singleton") { + singleton = true; ++ } else if (isRoot && line == "//@ pragma OmarchyLoadPatch") { ++ // Qt 6.12 added a QtQuick Color singleton which shadows Omarchy's Color singleton. ++ this->omarchyLoadPatch = true; + } else if (line.startsWith("import")) { + // we don't care about "import qs" as we always load the root folder + if (auto importCursor = line.indexOf(" qs."); importCursor != -1) { +@@ -226,6 +243,15 @@ bool QmlScanner::scanQmlFile(const QString& path, bool& singleton, bool& interna + } + } + ++ if (!sourceMasked && this->omarchyLoadPatch) { ++ auto patchedLine = ++ QString(rawLine).replace(unversionedQtQuickImport, QStringLiteral("\\1 6.11")); ++ if (patchedLine != rawLine) { ++ rawLine = patchedLine; ++ isOverridden = true; ++ } ++ } ++ + if (!hideMask && sourceMasked) overrideText.append("// MASKED: " % rawLine % '\n'); + else overrideText.append(rawLine % '\n'); + +@@ -285,7 +311,7 @@ bool QmlScanner::scanQmlFile(const QString& path, bool& singleton, bool& interna + void QmlScanner::scanQmlRoot(const QString& path) { + bool singleton = false; + bool internal = false; +- this->scanQmlFile(path, singleton, internal); ++ this->scanQmlFile(path, singleton, internal, true); + } + + bool QmlScanner::scanQmlJson(const QString& path) { +diff --git c/src/core/scan.hpp i/src/core/scan.hpp +index 7d807e1..932c0b0 100644 +--- c/src/core/scan.hpp ++++ i/src/core/scan.hpp +@@ -25,6 +25,7 @@ public: + QVector scannedFiles; + QHash fileHashes; + QHash fileIntercepts; ++ bool omarchyLoadPatch = false; + + struct ScanError { + QString file; +@@ -40,7 +41,7 @@ public: + private: + QDir rootPath; + +- bool scanQmlFile(const QString& path, bool& singleton, bool& internal); ++ bool scanQmlFile(const QString& path, bool& singleton, bool& internal, bool isRoot = false); + bool scanQmlJson(const QString& path); + [[nodiscard]] static QPair jsonToQml(const QJsonValue& value, int indent = 0); + +diff --git c/src/launch/launch.cpp i/src/launch/launch.cpp +index 1edd60c..f2542ae 100644 +--- c/src/launch/launch.cpp ++++ i/src/launch/launch.cpp +@@ -124,6 +124,8 @@ int launch(const LaunchArgs& args, char** argv) { + pragmas.stateDir = pragma.sliced(9).trimmed(); + } else if (pragma.startsWith("CacheDir ")) { + pragmas.cacheDir = pragma.sliced(9).trimmed(); ++ } else if (pragma == "OmarchyLoadPatch") { ++ // Applied later by the QML scanner. + } else { + qWarning() << "Unrecognized pragma" << pragma; + }