fix: set app locale after user's script is loaded (#26185)

* fix: set app locale after user's script is loaded

* fix: set LC_ALL env on Linux
This commit is contained in:
Cheng Zhao 2020-10-29 01:18:47 +09:00 committed by GitHub
parent 0c2e2bca92
commit d3f32c7502
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 55 deletions

View file

@ -8,10 +8,6 @@
#include <memory>
#include <string>
#if defined(OS_LINUX)
#include <glib.h> // for g_setenv()
#endif
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/environment.h"
@ -38,7 +34,6 @@
#include "shell/renderer/electron_renderer_client.h"
#include "shell/renderer/electron_sandboxed_renderer_client.h"
#include "shell/utility/electron_content_utility_client.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"
@ -110,12 +105,8 @@ void InvalidParameterHandler(const wchar_t*,
}
#endif
} // namespace
// TODO(nornagon): move path provider overriding to its own file in
// shell/common
namespace electron {
bool GetDefaultCrashDumpsPath(base::FilePath* path) {
base::FilePath cur;
if (!base::PathService::Get(DIR_USER_DATA, &cur))
@ -145,12 +136,11 @@ void RegisterPathProvider() {
PATH_END);
}
} // namespace electron
} // namespace
void LoadResourceBundle(const std::string& locale) {
std::string LoadResourceBundle(const std::string& locale) {
const bool initialized = ui::ResourceBundle::HasSharedInstance();
if (initialized)
ui::ResourceBundle::CleanupSharedInstance();
DCHECK(!initialized);
// Load other resource files.
base::FilePath pak_dir;
@ -161,12 +151,12 @@ void LoadResourceBundle(const std::string& locale) {
base::PathService::Get(base::DIR_MODULE, &pak_dir);
#endif
ui::ResourceBundle::InitSharedInstanceWithLocale(
std::string loaded_locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
bundle.ReloadLocaleResources(locale);
bundle.AddDataPackFromPath(pak_dir.Append(FILE_PATH_LITERAL("resources.pak")),
ui::SCALE_FACTOR_NONE);
return loaded_locale;
}
ElectronMainDelegate::ElectronMainDelegate() = default;
@ -285,36 +275,6 @@ bool ElectronMainDelegate::BasicStartupComplete(int* exit_code) {
return false;
}
void ElectronMainDelegate::PostEarlyInitialization(bool is_running_tests) {
std::string custom_locale;
ui::ResourceBundle::InitSharedInstanceWithLocale(
custom_locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
auto* cmd_line = base::CommandLine::ForCurrentProcess();
if (cmd_line->HasSwitch(::switches::kLang)) {
const std::string locale = cmd_line->GetSwitchValueASCII(::switches::kLang);
const base::FilePath locale_file_path =
ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(locale);
if (!locale_file_path.empty()) {
custom_locale = locale;
#if defined(OS_LINUX)
/* When built with USE_GLIB, libcc's GetApplicationLocaleInternal() uses
* glib's g_get_language_names(), which keys off of getenv("LC_ALL") */
g_setenv("LC_ALL", custom_locale.c_str(), TRUE);
#endif
}
}
#if defined(OS_MAC)
if (custom_locale.empty())
l10n_util::OverrideLocaleWithCocoaLocale();
#endif
LoadResourceBundle(custom_locale);
ElectronBrowserClient::SetApplicationLocale(
l10n_util::GetApplicationLocale(custom_locale));
}
void ElectronMainDelegate::PreSandboxStartup() {
auto* command_line = base::CommandLine::ForCurrentProcess();

View file

@ -17,7 +17,7 @@ class TracingSamplerProfiler;
namespace electron {
void LoadResourceBundle(const std::string& locale);
std::string LoadResourceBundle(const std::string& locale);
class ElectronMainDelegate : public content::ContentMainDelegate {
public:
@ -31,7 +31,6 @@ class ElectronMainDelegate : public content::ContentMainDelegate {
bool BasicStartupComplete(int* exit_code) override;
void PreSandboxStartup() override;
void PreCreateMainMessageLoop() override;
void PostEarlyInitialization(bool is_running_tests) override;
content::ContentBrowserClient* CreateContentBrowserClient() override;
content::ContentGpuClient* CreateContentGpuClient() override;
content::ContentRendererClient* CreateContentRendererClient() override;

View file

@ -8,10 +8,6 @@
#include <utility>
#if defined(OS_LINUX)
#include <glib.h> // for g_setenv()
#endif
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/feature_list.h"
@ -50,6 +46,7 @@
#include "shell/common/node_bindings.h"
#include "shell/common/node_includes.h"
#include "ui/base/idle/idle.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_switches.h"
#if defined(USE_AURA)
@ -89,7 +86,6 @@
#if defined(OS_WIN)
#include "ui/base/cursor/cursor_loader_win.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/display/win/dpi.h"
#include "ui/gfx/system_fonts_win.h"
@ -306,9 +302,36 @@ int ElectronBrowserMainParts::PreCreateThreads() {
if (!views::LayoutProvider::Get())
layout_provider_ = std::make_unique<views::LayoutProvider>();
auto* command_line = base::CommandLine::ForCurrentProcess();
std::string locale = command_line->GetSwitchValueASCII(::switches::kLang);
#if defined(OS_MAC)
// The browser process only wants to support the language Cocoa will use,
// so force the app locale to be overridden with that value. This must
// happen before the ResourceBundle is loaded
if (locale.empty())
l10n_util::OverrideLocaleWithCocoaLocale();
#elif defined(OS_LINUX)
// l10n_util::GetApplicationLocaleInternal uses g_get_language_names(),
// which keys off of getenv("LC_ALL").
// We must set this env first to make ui::ResourceBundle accept the custom
// locale.
g_setenv("LC_ALL", locale.c_str(), TRUE);
#endif
// Load resources bundle according to locale.
std::string loaded_locale = LoadResourceBundle(locale);
#if defined(OS_LINUX)
// Reset to the loaded locale if the custom locale is invalid.
if (loaded_locale != locale)
g_setenv("LC_ALL", loaded_locale.c_str(), TRUE);
#endif
// Initialize the app locale.
fake_browser_process_->SetApplicationLocale(
ElectronBrowserClient::Get()->GetApplicationLocale());
std::string app_locale = l10n_util::GetApplicationLocale(loaded_locale);
ElectronBrowserClient::SetApplicationLocale(app_locale);
fake_browser_process_->SetApplicationLocale(app_locale);
// Force MediaCaptureDevicesDispatcher to be created on UI thread.
MediaCaptureDevicesDispatcher::GetInstance();

View file

@ -302,7 +302,7 @@ describe('command line switches', () => {
const testLocale = async (locale: string, result: string) => {
const appPath = path.join(fixturesPath, 'api', 'locale-check');
const electronPath = process.execPath;
appProcess = ChildProcess.spawn(electronPath, [appPath, `--lang=${locale}`]);
appProcess = ChildProcess.spawn(electronPath, [appPath, `--set-lang=${locale}`]);
let output = '';
appProcess.stdout.on('data', (data) => { output += data; });

View file

@ -1,5 +1,8 @@
const { app } = require('electron');
const locale = process.argv[2].substr(11);
app.commandLine.appendSwitch('lang', locale);
app.whenReady().then(() => {
process.stdout.write(app.getLocale());
process.stdout.end();