11#include " common.h"
22#include " ../fcitx5/src/lib/fcitx/addonmanager.h"
33#include " nativestreambuf.h"
4+ #include < fcitx-utils/i18n.h>
45#include < filesystem>
5-
66#include < thread>
77
88namespace fs = std::filesystem;
@@ -43,10 +43,48 @@ void setupEnv(const char *bundlePath, const char *appGroupPath,
4343 setenv (" FCITX_CONFIG_HOME" , fcitx_config_home.c_str (), 1 );
4444}
4545
46+ // Collect all share/locale/*/LC_MESSAGES/*.mo
47+ std::set<std::string> getAllDomains (const fs::path &localedir) {
48+ std::set<std::string> ret;
49+ try {
50+ for (const auto &entry : fs::directory_iterator (localedir)) {
51+ if (!entry.is_directory ()) {
52+ continue ;
53+ }
54+ fs::path lcMessagesPath = entry.path () / " LC_MESSAGES" ;
55+ try {
56+ for (const auto &file :
57+ fs::directory_iterator (lcMessagesPath)) {
58+ if (file.path ().extension () == " .mo" ) {
59+ ret.insert (file.path ().stem ());
60+ }
61+ }
62+ } catch (const std::exception &e) {
63+ // LC_MESSAGES not exist.
64+ }
65+ }
66+ } catch (const std::exception &e) {
67+ // localedir not exist.
68+ }
69+ return ret;
70+ }
71+
72+ // Must be executed before creating fcitx instance, i.e. loading addons, because
73+ // addons register compile-time domain path, and only 1st call of registerDomain
74+ // counts. The .mo files must exist.
75+ void setupI18N (const char *bundlePath) {
76+ fs::path bundle = bundlePath;
77+ fs::path localedir = bundle / " share" / " locale" ;
78+ for (const auto &domain : getAllDomains (localedir)) {
79+ fcitx::registerDomain (domain.c_str (), localedir);
80+ }
81+ }
82+
4683void setupFcitx (const char *bundlePath, const char *appGroupPath,
4784 bool isMainApp) {
4885 setupLog ();
4986 setupEnv (bundlePath, appGroupPath, isMainApp);
87+ setupI18N (bundlePath);
5088
5189 instance = std::make_unique<fcitx::Instance>(0 , nullptr );
5290 instance->setInputMethodMode (fcitx::InputMethodMode::OnScreenKeyboard);
@@ -59,3 +97,12 @@ void setupFcitx(const char *bundlePath, const char *appGroupPath,
5997 dispatcher->attach (&instance->eventLoop ());
6098 fcitx_thread = std::thread ([] { instance->eventLoop ().exec (); });
6199}
100+
101+ void setLocale (const char *locale) {
102+ std::string val = locale;
103+ val += " :C" ;
104+ // For config items.
105+ setenv (" LANGUAGE" , val.c_str (), 1 );
106+ // For addon names.
107+ setenv (" FCITX_LOCALE" , val.c_str (), 1 );
108+ }
0 commit comments