|
11 | 11 | #include <cstring> |
12 | 12 | #include <fmt/format.h> |
13 | 13 | #include <libintl.h> |
| 14 | +#include <xkbcommon/xkbcommon.h> |
14 | 15 | #include "fcitx-config/iniparser.h" |
15 | 16 | #include "fcitx-utils/charutils.h" |
16 | 17 | #include "fcitx-utils/cutf8.h" |
@@ -166,25 +167,41 @@ KeyboardEngineState::KeyboardEngineState(KeyboardEngine *engine, |
166 | 167 | KeyboardEngine::KeyboardEngine(Instance *instance) : instance_(instance) { |
167 | 168 | setupDefaultLongPressConfig(longPressConfig_); |
168 | 169 | registerDomain("xkeyboard-config", XKEYBOARDCONFIG_DATADIR "/locale"); |
169 | | - std::string rule; |
| 170 | + std::string ruleName = DEFAULT_XKB_RULES; |
| 171 | + std::string extraRuleFile; |
170 | 172 | #ifdef ENABLE_X11 |
171 | 173 | auto *xcb = instance_->addonManager().addon("xcb"); |
172 | 174 | if (xcb) { |
173 | 175 | auto rules = xcb->call<IXCBModule::xkbRulesNames>(""); |
174 | 176 | if (!rules[0].empty()) { |
175 | | - rule = rules[0]; |
176 | | - if (rule[0] != '/') { |
177 | | - rule = XKEYBOARDCONFIG_XKBBASE "/rules/" + rule; |
| 177 | + if (rules[0][0] == '/') { |
| 178 | + extraRuleFile = rules[0]; |
| 179 | + if (!stringutils::endsWith(extraRuleFile, ".xml")) { |
| 180 | + extraRuleFile = extraRuleFile + ".xml"; |
| 181 | + } |
| 182 | + } else { |
| 183 | + ruleName = rules[0]; |
178 | 184 | } |
179 | | - rule += ".xml"; |
180 | | - ruleName_ = rule; |
181 | 185 | } |
182 | 186 | } |
183 | 187 | #endif |
184 | | - if (rule.empty() || !xkbRules_.read(rule)) { |
185 | | - rule = XKEYBOARDCONFIG_XKBBASE "/rules/" DEFAULT_XKB_RULES ".xml"; |
186 | | - xkbRules_.read(rule); |
187 | | - ruleName_ = DEFAULT_XKB_RULES; |
| 188 | + |
| 189 | + UniqueCPtr<xkb_context, xkb_context_unref> xkbContext( |
| 190 | + xkb_context_new(XKB_CONTEXT_NO_FLAGS)); |
| 191 | + std::vector<std::string> directories; |
| 192 | + if (xkbContext) { |
| 193 | + for (unsigned int i = 0, |
| 194 | + e = xkb_context_num_include_paths(xkbContext.get()); |
| 195 | + i < e; i++) { |
| 196 | + directories.push_back( |
| 197 | + xkb_context_include_path_get(xkbContext.get(), i)); |
| 198 | + } |
| 199 | + } |
| 200 | + if (directories.empty()) { |
| 201 | + directories.push_back(XKEYBOARDCONFIG_XKBBASE); |
| 202 | + } |
| 203 | + if (!xkbRules_.read(directories, ruleName, extraRuleFile)) { |
| 204 | + xkbRules_.read(directories, DEFAULT_XKB_RULES, ""); |
188 | 205 | } |
189 | 206 |
|
190 | 207 | instance_->inputContextManager().registerProperty("keyboardState", |
|
0 commit comments