(Windows) Fixed an issue where translations didn't work correctly for some text

This commit is contained in:
Leon Styhre 2024-11-12 19:56:16 +01:00
parent 1a4648622a
commit 4c5cabc5fc
6 changed files with 63 additions and 3 deletions

View file

@ -116,6 +116,11 @@ void ApplicationUpdater::checkForUpdates()
void ApplicationUpdater::updaterThread() void ApplicationUpdater::updaterThread()
{ {
#if defined(_WIN64)
// Workaround for a bug in the libintl library.
Utils::Localization::setThreadLocale();
#endif
if (!downloadFile()) if (!downloadFile())
compareVersions(); compareVersions();

View file

@ -31,6 +31,11 @@ MiximageGenerator::MiximageGenerator(FileData* game, std::string& resultMessage)
void MiximageGenerator::startThread(std::promise<bool>* miximagePromise) void MiximageGenerator::startThread(std::promise<bool>* miximagePromise)
{ {
#if defined(_WIN64)
// Workaround for a bug in the libintl library.
Utils::Localization::setThreadLocale();
#endif
mMiximagePromise = miximagePromise; mMiximagePromise = miximagePromise;
LOG(LogDebug) << "MiximageGenerator::MiximageGenerator(): Creating miximage for \"" LOG(LogDebug) << "MiximageGenerator::MiximageGenerator(): Creating miximage for \""

View file

@ -304,6 +304,11 @@ GuiOrphanedDataCleanup::~GuiOrphanedDataCleanup()
void GuiOrphanedDataCleanup::cleanupMediaFiles() 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"; LOG(LogInfo) << "GuiOrphanedDataCleanup: Starting cleanup of game media";
const std::time_t currentTime { const std::time_t currentTime {
@ -492,6 +497,11 @@ void GuiOrphanedDataCleanup::cleanupMediaFiles()
void GuiOrphanedDataCleanup::cleanupGamelists() 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"; LOG(LogInfo) << "GuiOrphanedDataCleanup: Starting cleanup of gamelist.xml files";
if (!Settings::getInstance()->getBool("ShowHiddenGames")) { if (!Settings::getInstance()->getBool("ShowHiddenGames")) {
@ -808,6 +818,11 @@ void GuiOrphanedDataCleanup::cleanupGamelists()
void GuiOrphanedDataCleanup::cleanupCollections() void GuiOrphanedDataCleanup::cleanupCollections()
{ {
#if defined(_WIN64)
// Workaround for a bug in the libintl library.
Utils::Localization::setThreadLocale();
#endif
LOG(LogInfo) LOG(LogInfo)
<< "GuiOrphanedDataCleanup: Starting cleanup of custom collections configuration files"; << "GuiOrphanedDataCleanup: Starting cleanup of custom collections configuration files";

View file

@ -228,6 +228,11 @@ GuiThemeDownloader::~GuiThemeDownloader()
bool GuiThemeDownloader::fetchRepository(const std::string& repositoryName, bool allowReset) 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}; int errorCode {0};
const std::string path {mThemeDirectory + repositoryName}; const std::string path {mThemeDirectory + repositoryName};
mRepositoryError = RepositoryError::NO_REPO_ERROR; mRepositoryError = RepositoryError::NO_REPO_ERROR;

View file

@ -49,6 +49,9 @@ namespace Utils
std::string sCurrentLocale {"en_US"}; std::string sCurrentLocale {"en_US"};
float sMenuTitleScaleFactor {1.0f}; float sMenuTitleScaleFactor {1.0f};
#if defined(_WIN64)
unsigned long sLocaleID {0};
#endif
const char* pgettextBuiltin(const char* msgctxt, const char* msgid) const char* pgettextBuiltin(const char* msgctxt, const char* msgid)
{ {
@ -236,9 +239,9 @@ namespace Utils
#if defined(_WIN64) #if defined(_WIN64)
_configthreadlocale(_DISABLE_PER_THREAD_LOCALE); _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
const LCID localeID {LocaleNameToLCID(Utils::String::stringToWideString(locale).c_str(), sLocaleID = LocaleNameToLCID(Utils::String::stringToWideString(locale).c_str(),
LOCALE_ALLOW_NEUTRAL_NAMES)}; LOCALE_ALLOW_NEUTRAL_NAMES);
SetThreadLocale(localeID); SetThreadLocale(sLocaleID);
#else #else
setenv("LANGUAGE", locale.c_str(), 1); setenv("LANGUAGE", locale.c_str(), 1);
setenv("LANG", locale.c_str(), 1); setenv("LANG", locale.c_str(), 1);
@ -256,6 +259,27 @@ namespace Utils
sCurrentLocale = locale; 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 Localization
} // namespace Utils } // namespace Utils

View file

@ -25,6 +25,9 @@ namespace Utils
{ {
extern const std::vector<std::pair<std::string, std::string>> sSupportedLocales; extern const std::vector<std::pair<std::string, std::string>> sSupportedLocales;
extern std::string sCurrentLocale; extern std::string sCurrentLocale;
#if defined(_WIN64)
extern unsigned long sLocaleID;
#endif
extern float sMenuTitleScaleFactor; extern float sMenuTitleScaleFactor;
const char* pgettextBuiltin(const char* msgctxt, const char* msgid); const char* pgettextBuiltin(const char* msgctxt, const char* msgid);
@ -34,6 +37,9 @@ namespace Utils
unsigned long int n); unsigned long int n);
std::pair<std::string, std::string> getLocale(); std::pair<std::string, std::string> getLocale();
void setLocale(); void setLocale();
#if defined(_WIN64)
void setThreadLocale();
#endif
} // namespace Localization } // namespace Localization