aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-05-15 17:15:58 -0500
committerSulfurNitride <lukew19@proton.me>2026-05-16 12:57:25 -0500
commit25c189f4de8288e1c65002b52d6d293be6c5b7cb (patch)
tree6493c549da46a86cfd63b550cda08a73f7bd1f69
parentfe424eef00692482b859c9b23e86b8fb814754fd (diff)
themes: shim asset case both ways for QSS url() refs
Stylesheet themes ported from Windows can reference assets with either case convention - some QSS files use lowercase url() refs against MixedCase.svg files on disk, others do the reverse. The original shim only covered the first direction. Add the second so themes whose disk assets are lowercase but whose QSS uses TitleCase also resolve on case-sensitive filesystems. Rename createLowercaseStylesheetShims -> createStylesheetCaseShims and extract the symlink-creation into a tryShim lambda that's called twice per file (lowercase + TitleCase target names). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
-rw-r--r--src/src/moapplication.cpp49
1 files changed, 31 insertions, 18 deletions
diff --git a/src/src/moapplication.cpp b/src/src/moapplication.cpp
index ce05b3a..dda52e7 100644
--- a/src/src/moapplication.cpp
+++ b/src/src/moapplication.cpp
@@ -851,13 +851,13 @@ QString extractBaseStyleFromStyleSheet(QFile& stylesheet, const QString& default
} // namespace
-// Walk a directory and create lowercase symlinks for any file whose name
-// contains uppercase letters, if the lowercase name doesn't already exist.
-// QSS files authored on Windows often reference asset files with lowercase
-// names but the actual files on disk use mixed case — on a case-sensitive
-// filesystem Qt's url() resolver fails. Shimming lowercase symlinks lets the
-// existing paths resolve without touching the original files.
-static void createLowercaseStylesheetShims(const QString& dirPath)
+// Walk a directory and create case-variant symlinks for asset files so QSS
+// url(...) references resolve regardless of the case convention the theme
+// author used. On case-sensitive filesystems Qt's url() resolver fails when
+// the case doesn't match exactly. We cover the two common conventions:
+// - QSS lowercase / disk mixed case → create lowercase → MixedCase symlink
+// - QSS TitleCase / disk lowercase → create TitleCase → lowercase symlink
+static void createStylesheetCaseShims(const QString& dirPath)
{
namespace fs = std::filesystem;
std::error_code ec;
@@ -865,6 +865,21 @@ static void createLowercaseStylesheetShims(const QString& dirPath)
!fs::is_directory(dirPath.toStdString(), ec)) {
return;
}
+
+ auto tryShim = [](const fs::path& parent, const std::string& target,
+ const std::string& shimName) {
+ if (shimName == target) return;
+ std::error_code ec;
+ const auto shimPath = parent / shimName;
+ if (fs::exists(shimPath, ec)) return;
+ std::error_code lec;
+ fs::create_symlink(target, shimPath, lec);
+ if (lec) {
+ log::debug("stylesheet shim: failed to link '{}' -> '{}': {}",
+ shimPath.string(), target, lec.message());
+ }
+ };
+
for (auto it = fs::recursive_directory_iterator(
dirPath.toStdString(),
fs::directory_options::skip_permission_denied, ec);
@@ -873,21 +888,19 @@ static void createLowercaseStylesheetShims(const QString& dirPath)
if (!entry.is_regular_file(ec)) continue;
const std::string name = entry.path().filename().string();
+ const auto parent = entry.path().parent_path();
+
std::string lowerName = name;
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(),
[](unsigned char c) { return std::tolower(c); });
- if (lowerName == name) continue; // already lowercase
-
- const auto parent = entry.path().parent_path();
- const auto lowerPath = parent / lowerName;
- if (fs::exists(lowerPath, ec)) continue;
+ tryShim(parent, name, lowerName);
- std::error_code lec;
- fs::create_symlink(name, lowerPath, lec);
- if (lec) {
- log::debug("stylesheet shim: failed to link '{}' -> '{}': {}",
- lowerPath.string(), name, lec.message());
+ std::string titleName = lowerName;
+ if (!titleName.empty()) {
+ titleName[0] = static_cast<char>(
+ std::toupper(static_cast<unsigned char>(titleName[0])));
}
+ tryShim(parent, name, titleName);
}
}
@@ -901,7 +914,7 @@ void MOApplication::updateStyle(const QString& fileName)
if (stylesheet.exists()) {
// Pre-create lowercase shims so url(foo.svg) in the QSS resolves even
// when the on-disk file is Foo.svg.
- createLowercaseStylesheetShims(QFileInfo(fileName).absolutePath());
+ createStylesheetCaseShims(QFileInfo(fileName).absolutePath());
setStyle(new ProxyStyle(QStyleFactory::create(
extractBaseStyleFromStyleSheet(stylesheet, m_defaultStyle))));
setStyleSheet(QString("file:///%1").arg(fileName));