aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-04-18 10:41:56 -0500
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-04-18 10:41:56 -0500
commit915298db2a22213441c5da909786ccc0db64bbaa (patch)
treedc6df417ba015e8917ebc7f89aec1350bdcb31c9
parent4279200bd015d79179961f02a1b4d1544c61ff52 (diff)
Force C.UTF-8 locale for Proton when user env isn't UTF-8
Wine picks its Unix codepage from LC_ALL/LC_CTYPE/LANG via nl_langinfo(CODESET); a C/POSIX locale falls back to CP1252, so non-ASCII Linux filenames (CJK, Cyrillic) fail UTF-8→UTF-16 conversion and MSVC std::filesystem throws "Invalid name" when Windows tools like PGPatcher iterate mod dirs through the Z:\ drive. Steam's pressure-vessel can strip the user locale, triggering this. Detect UTF-8 in LC_ALL/LC_CTYPE/LANG and only inject C.UTF-8 when none is UTF-8 already — preserves de_DE.UTF-8, ja_JP.UTF-8, etc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
-rw-r--r--src/src/protonlauncher.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/src/protonlauncher.cpp b/src/src/protonlauncher.cpp
index 458d20f..c1b6b64 100644
--- a/src/src/protonlauncher.cpp
+++ b/src/src/protonlauncher.cpp
@@ -553,6 +553,35 @@ bool ProtonLauncher::launchWithProton(qint64& pid) const
env.insert("DOTNET_ROOT", "");
env.insert("DOTNET_MULTILEVEL_LOOKUP", "0");
+ // Ensure Wine's Unix codepage is UTF-8 so non-ASCII filenames (CJK,
+ // Cyrillic, accented Latin) round-trip correctly between Linux FS and
+ // Win32 WCHAR APIs. Wine picks the codepage from LC_ALL > LC_CTYPE >
+ // LANG via nl_langinfo(CODESET); a C/POSIX locale collapses to CP1252
+ // and makes MSVC std::filesystem throw "Invalid name" on CJK entries
+ // (WineHQ#46039, Proton#3434). Steam's pressure-vessel can strip the
+ // user's locale, so we override only if no UTF-8 locale is already set
+ // — keeps de_DE.UTF-8, ja_JP.UTF-8 etc. intact for users who have them.
+ {
+ const auto isUtf8 = [](const QString& v) {
+ return v.contains("UTF-8", Qt::CaseInsensitive) ||
+ v.contains("UTF8", Qt::CaseInsensitive);
+ };
+ const QString lcAll = env.value("LC_ALL");
+ const QString lcCtype = env.value("LC_CTYPE");
+ const QString lang = env.value("LANG");
+ const bool haveUtf8 =
+ (!lcAll.isEmpty() && isUtf8(lcAll)) ||
+ (lcAll.isEmpty() && !lcCtype.isEmpty() && isUtf8(lcCtype)) ||
+ (lcAll.isEmpty() && lcCtype.isEmpty() && isUtf8(lang));
+ if (!haveUtf8) {
+ MOBase::log::info("Locale not UTF-8 (LC_ALL='{}', LC_CTYPE='{}', "
+ "LANG='{}'); forcing C.UTF-8 for Wine",
+ lcAll, lcCtype, lang);
+ env.insert("LC_ALL", "C.UTF-8");
+ env.insert("LANG", "C.UTF-8");
+ }
+ }
+
// Force-disable DXVK graphics-pipeline-library. GPL causes very long shader
// compile stalls on first launch for heavily modded Bethesda games and the
// benefit is modest for us. We write a small dxvk.conf into the prefix and