diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-04-18 10:41:56 -0500 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-04-18 10:41:56 -0500 |
| commit | 915298db2a22213441c5da909786ccc0db64bbaa (patch) | |
| tree | dc6df417ba015e8917ebc7f89aec1350bdcb31c9 /src | |
| parent | 4279200bd015d79179961f02a1b4d1544c61ff52 (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>
Diffstat (limited to 'src')
| -rw-r--r-- | src/src/protonlauncher.cpp | 29 |
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 |
