Skip to content

Commit ddc3398

Browse files
committed
frontend: Use system locale instead of 'C'
Sets runtime locale to system locale with UTF-8 codepage. This is already default behavior on unix, but Windows defaults to minimal 'C' locale. Use CRT locale for C++ std::locale default OBS Studio language settings no longer change QLocale default locale, instead system locale is used for conformity. It is likely this is what user wants as well. Ie. sorting and formatting functions should follow OS locale instead of OBS Studio language (which also lacks country information).
1 parent dc3d449 commit ddc3398

2 files changed

Lines changed: 54 additions & 17 deletions

File tree

frontend/OBSApp.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -724,11 +724,6 @@ bool OBSApp::InitLocale()
724724

725725
locale = lang;
726726

727-
// set basic default application locale
728-
if (!locale.empty()) {
729-
QLocale::setDefault(QLocale(QString::fromStdString(locale).replace('-', '_')));
730-
}
731-
732727
string englishPath;
733728
if (!GetDataFilePath("locale/" DEFAULT_LANG ".ini", englishPath)) {
734729
OBSErrorBox(NULL, "Failed to find locale/" DEFAULT_LANG ".ini");
@@ -768,11 +763,6 @@ bool OBSApp::InitLocale()
768763
blog(LOG_INFO, "Using preferred locale '%s'", locale_.c_str());
769764
locale = locale_;
770765

771-
// set application default locale to the new chosen one
772-
if (!locale.empty()) {
773-
QLocale::setDefault(QLocale(QString::fromStdString(locale).replace('-', '_')));
774-
}
775-
776766
return true;
777767
}
778768

@@ -914,13 +904,6 @@ OBSApp::OBSApp(int &argc, char **argv, profiler_name_store_t *store)
914904
{
915905
installNativeEventFilter(new OBS::NativeEventFilter);
916906

917-
/* fix float handling */
918-
#if defined(Q_OS_UNIX)
919-
if (!setlocale(LC_NUMERIC, "C")) {
920-
blog(LOG_WARNING, "Failed to set LC_NUMERIC to C locale");
921-
}
922-
#endif
923-
924907
#ifndef _WIN32
925908
// Add POSIX signal handlers:
926909
// * SIGINT

frontend/obs-main.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <shellapi.h>
4646
#define WIN32_LEAN_AND_MEAN
4747
#include <windows.h>
48+
#include <mbctype.h>
4849
#else
4950
#include <signal.h>
5051
#endif
@@ -77,6 +78,7 @@ bool opt_disable_missing_files_check = false;
7778
string opt_starting_collection;
7879
string opt_starting_profile;
7980
string opt_starting_scene;
81+
bool using_utf8 = false;
8082

8183
bool restart = false;
8284
bool restart_safe = false;
@@ -416,6 +418,42 @@ static void create_log_file(fstream &logFile)
416418
}
417419
}
418420

421+
static bool set_utf8_locale(void)
422+
{
423+
// Use system locale with UTF-8 codepage (available from Windows 10 version 1803)
424+
bool usingUTF8 = !!setlocale(LC_ALL, ".UTF-8");
425+
426+
/*
427+
Fallback to minimal C locale
428+
Could use "" for system defaults, but the Windows default ANSI codepages (such as .125x or .9xx)
429+
mismatch with UTF-8 that is assumed by many parts of the codebase. "C" only covers ASCII, so no mismatches.
430+
*/
431+
usingUTF8 = usingUTF8 || !!setlocale(LC_ALL, "C.UTF-8");
432+
433+
#ifdef _WIN32
434+
usingUTF8 = usingUTF8 && (_setmbcp(CP_UTF8) == 0);
435+
#endif
436+
if (!usingUTF8) {
437+
setlocale(LC_ALL, "C");
438+
}
439+
440+
// fix float handling
441+
setlocale(LC_NUMERIC, "C");
442+
443+
// Copy C runtime locale for C++
444+
std::locale defaultLocale(setlocale(LC_ALL, nullptr));
445+
std::locale::global(defaultLocale);
446+
447+
/*
448+
system() is already the QLocale default, but just to be explicit about the intention.
449+
Unlike CRT and C++ locales above, QLocale doesn't support customization of locale categories and codepages.
450+
Ie. We can't enforce decimal point to be a dot and at the same time use user's preferred locale.
451+
*/
452+
QLocale::setDefault(QLocale::system());
453+
454+
return usingUTF8;
455+
}
456+
419457
static auto ProfilerNameStoreRelease = [](profiler_name_store_t *store) {
420458
profiler_name_store_free(store);
421459
};
@@ -533,6 +571,12 @@ static int run_program(fstream &logFile, int argc, char *argv[])
533571
qputenv("QT_NO_SUBTRACTOPAQUESIBLINGS", "1");
534572

535573
OBSApp program(argc, argv, profilerNameStore.get());
574+
575+
#if defined(Q_OS_UNIX)
576+
// OBSApp (QApplication) constructor overwrote the locale for unix, so set it again
577+
set_utf8_locale();
578+
#endif
579+
536580
try {
537581
QAccessible::installFactory(accessibleFactory);
538582
QFontDatabase::addApplicationFont(":/fonts/OpenSans-Regular.ttf");
@@ -683,6 +727,15 @@ static int run_program(fstream &logFile, int argc, char *argv[])
683727
blog(LOG_INFO, "Command Line Arguments: %s", stor.str().c_str());
684728
}
685729

730+
if (!using_utf8) {
731+
blog(LOG_DEBUG, "UTF-8 locale is not available on this OS version. "
732+
"Skipping regional formatting and sorting.");
733+
}
734+
735+
// Use collation (sorting rules) as indicator of regional settings
736+
blog(LOG_DEBUG, "Locale: %s", setlocale(LC_COLLATE, nullptr));
737+
blog(LOG_DEBUG, "App language: %s", program.GetLocale());
738+
686739
if (!program.OBSInit()) {
687740
return 0;
688741
}
@@ -903,6 +956,7 @@ static void set_process_mitigation_policies()
903956

904957
int main(int argc, char *argv[])
905958
{
959+
using_utf8 = set_utf8_locale();
906960
#ifndef _WIN32
907961
using SignalHandlerCallback = decltype(OBSApp::sigIntSignalHandler);
908962

0 commit comments

Comments
 (0)