From 4c5cabc5fcab8c565429842c71ced02ee63246c1 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Tue, 12 Nov 2024 19:56:16 +0100 Subject: [PATCH] (Windows) Fixed an issue where translations didn't work correctly for some text --- es-app/src/ApplicationUpdater.cpp | 5 ++++ es-app/src/MiximageGenerator.cpp | 5 ++++ es-app/src/guis/GuiOrphanedDataCleanup.cpp | 15 +++++++++++ es-app/src/guis/GuiThemeDownloader.cpp | 5 ++++ es-core/src/utils/LocalizationUtil.cpp | 30 +++++++++++++++++++--- es-core/src/utils/LocalizationUtil.h | 6 +++++ 6 files changed, 63 insertions(+), 3 deletions(-) diff --git a/es-app/src/ApplicationUpdater.cpp b/es-app/src/ApplicationUpdater.cpp index b3564019e..7e7cc2fac 100644 --- a/es-app/src/ApplicationUpdater.cpp +++ b/es-app/src/ApplicationUpdater.cpp @@ -116,6 +116,11 @@ void ApplicationUpdater::checkForUpdates() void ApplicationUpdater::updaterThread() { +#if defined(_WIN64) + // Workaround for a bug in the libintl library. + Utils::Localization::setThreadLocale(); +#endif + if (!downloadFile()) compareVersions(); diff --git a/es-app/src/MiximageGenerator.cpp b/es-app/src/MiximageGenerator.cpp index c2b6d4b04..6dad778c6 100644 --- a/es-app/src/MiximageGenerator.cpp +++ b/es-app/src/MiximageGenerator.cpp @@ -31,6 +31,11 @@ MiximageGenerator::MiximageGenerator(FileData* game, std::string& resultMessage) void MiximageGenerator::startThread(std::promise* miximagePromise) { +#if defined(_WIN64) + // Workaround for a bug in the libintl library. + Utils::Localization::setThreadLocale(); +#endif + mMiximagePromise = miximagePromise; LOG(LogDebug) << "MiximageGenerator::MiximageGenerator(): Creating miximage for \"" diff --git a/es-app/src/guis/GuiOrphanedDataCleanup.cpp b/es-app/src/guis/GuiOrphanedDataCleanup.cpp index 13dba214e..bffa9436c 100644 --- a/es-app/src/guis/GuiOrphanedDataCleanup.cpp +++ b/es-app/src/guis/GuiOrphanedDataCleanup.cpp @@ -304,6 +304,11 @@ GuiOrphanedDataCleanup::~GuiOrphanedDataCleanup() void GuiOrphanedDataCleanup::cleanupMediaFiles() { +#if defined(_WIN64) + // Workaround for a bug in the libintl library. + Utils::Localization::setThreadLocale(); +#endif + LOG(LogInfo) << "GuiOrphanedDataCleanup: Starting cleanup of game media"; const std::time_t currentTime { @@ -492,6 +497,11 @@ void GuiOrphanedDataCleanup::cleanupMediaFiles() void GuiOrphanedDataCleanup::cleanupGamelists() { +#if defined(_WIN64) + // Workaround for a bug in the libintl library. + Utils::Localization::setThreadLocale(); +#endif + LOG(LogInfo) << "GuiOrphanedDataCleanup: Starting cleanup of gamelist.xml files"; if (!Settings::getInstance()->getBool("ShowHiddenGames")) { @@ -808,6 +818,11 @@ void GuiOrphanedDataCleanup::cleanupGamelists() void GuiOrphanedDataCleanup::cleanupCollections() { +#if defined(_WIN64) + // Workaround for a bug in the libintl library. + Utils::Localization::setThreadLocale(); +#endif + LOG(LogInfo) << "GuiOrphanedDataCleanup: Starting cleanup of custom collections configuration files"; diff --git a/es-app/src/guis/GuiThemeDownloader.cpp b/es-app/src/guis/GuiThemeDownloader.cpp index 45bb60b69..a79fff4a5 100644 --- a/es-app/src/guis/GuiThemeDownloader.cpp +++ b/es-app/src/guis/GuiThemeDownloader.cpp @@ -228,6 +228,11 @@ GuiThemeDownloader::~GuiThemeDownloader() bool GuiThemeDownloader::fetchRepository(const std::string& repositoryName, bool allowReset) { +#if defined(_WIN64) + // Workaround for a bug in the libintl library. + Utils::Localization::setThreadLocale(); +#endif + int errorCode {0}; const std::string path {mThemeDirectory + repositoryName}; mRepositoryError = RepositoryError::NO_REPO_ERROR; diff --git a/es-core/src/utils/LocalizationUtil.cpp b/es-core/src/utils/LocalizationUtil.cpp index f0bf56890..95f04c4a9 100644 --- a/es-core/src/utils/LocalizationUtil.cpp +++ b/es-core/src/utils/LocalizationUtil.cpp @@ -49,6 +49,9 @@ namespace Utils std::string sCurrentLocale {"en_US"}; float sMenuTitleScaleFactor {1.0f}; +#if defined(_WIN64) + unsigned long sLocaleID {0}; +#endif const char* pgettextBuiltin(const char* msgctxt, const char* msgid) { @@ -236,9 +239,9 @@ namespace Utils #if defined(_WIN64) _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); - const LCID localeID {LocaleNameToLCID(Utils::String::stringToWideString(locale).c_str(), - LOCALE_ALLOW_NEUTRAL_NAMES)}; - SetThreadLocale(localeID); + sLocaleID = LocaleNameToLCID(Utils::String::stringToWideString(locale).c_str(), + LOCALE_ALLOW_NEUTRAL_NAMES); + SetThreadLocale(sLocaleID); #else setenv("LANGUAGE", locale.c_str(), 1); setenv("LANG", locale.c_str(), 1); @@ -256,6 +259,27 @@ namespace Utils sCurrentLocale = locale; } +#if defined(_WIN64) + void setThreadLocale() + { + // This is essentially a workaround for what seems to be a bug in the libintl library + // where _configthreadlocale(_DISABLE_PER_THREAD_LOCALE) does not have the expected + // effect. If gettext() is called from a child thread and the string has not been + // translated already from the main thread then it will not get translated to the + // selected locale. If however the string is first translated on the main thread and + // then translated again from the child thread it works correctly. However, if calling + // SetThreadLocale() from the child thread before attempting any translations then + // everything behaves as expected which feels like a cleaner workaround than having + // to make every single translation from the main thread that we want to use in any + // child threads. + + if (sLocaleID == 0) + return; + + SetThreadLocale(sLocaleID); + } +#endif + } // namespace Localization } // namespace Utils diff --git a/es-core/src/utils/LocalizationUtil.h b/es-core/src/utils/LocalizationUtil.h index 9f29e0b18..5bac31f5d 100644 --- a/es-core/src/utils/LocalizationUtil.h +++ b/es-core/src/utils/LocalizationUtil.h @@ -25,6 +25,9 @@ namespace Utils { extern const std::vector> sSupportedLocales; extern std::string sCurrentLocale; +#if defined(_WIN64) + extern unsigned long sLocaleID; +#endif extern float sMenuTitleScaleFactor; const char* pgettextBuiltin(const char* msgctxt, const char* msgid); @@ -34,6 +37,9 @@ namespace Utils unsigned long int n); std::pair getLocale(); void setLocale(); +#if defined(_WIN64) + void setThreadLocale(); +#endif } // namespace Localization