8 #include "globalconfig.h" 13 #include "fcitx-config/configuration.h" 14 #include "fcitx-config/enum.h" 15 #include "fcitx-config/iniparser.h" 16 #include "fcitx-config/option.h" 17 #include "fcitx-config/rawconfig.h" 18 #include "fcitx-utils/eventloopinterface.h" 19 #include "fcitx-utils/i18n.h" 21 #include "fcitx-utils/macros.h" 22 #include "fcitx-utils/misc.h" 24 #include "inputcontextmanager.h" 30 #ifdef ENABLE_KEYBOARD 31 constexpr
bool hasKeyboard =
true;
33 constexpr
bool hasKeyboard =
false;
36 FCITX_CONFIG_ENUM_I18N_ANNOTATION(PropertyPropagatePolicy, N_(
"All"),
37 N_(
"Program"), N_(
"No"));
41 KeyListOption triggerKeys{
44 _(
"Toggle Input Method"),
45 {isApple() ? Key(
"Control+Shift_L") : Key(
"Control+space"),
46 Key(
"Zenkaku_Hankaku"), Key(
"Hangul")},
47 KeyListConstrain({KeyConstrainFlag::AllowModifierLess,
48 KeyConstrainFlag::AllowModifierOnly})};
49 OptionWithAnnotation<bool, ToolTipAnnotation> enumerateWithTriggerKeys{{
51 .path{
"EnumerateWithTriggerKeys"},
52 .description{_(
"Enumerate when holding modifier of Toggle key")},
55 _(
"For example, if Control+Space is the toggle key, after pressing " 56 "Control+Space for the first time, if Control is held, following " 57 "key press of Space will enumerate the input method.")},
59 KeyListOption activateKeys{
62 _(
"Activate Input Method"),
66 KeyListConstrain({KeyConstrainFlag::AllowModifierLess,
67 KeyConstrainFlag::AllowModifierOnly})};
68 KeyListOption deactivateKeys{
71 _(
"Deactivate Input Method"),
72 {Key(
"Hangul_Romaja")},
73 KeyListConstrain({KeyConstrainFlag::AllowModifierLess,
74 KeyConstrainFlag::AllowModifierOnly})};
75 OptionWithAnnotation<bool, ToolTipAnnotation> consumeRedundantActivateKeys{{
77 .path{
"ConsumeRedundantActivateKeys"},
78 .description{_(
"Consume redundant Activate/Deactivate key")},
79 .defaultValue =
false,
81 _(
"When the input method is already in the state the key " 82 "requests, pressing an Activate/Deactivate key changes " 83 "nothing; consume the key event in that case instead of " 84 "forwarding it to the application. Modifier only keys are " 87 KeyListOptionWithAnnotation<ToolTipAnnotation> altTriggerKeys{
89 .path{
"AltTriggerKeys"},
90 .description{_(
"Temporarily Toggle Input Method")},
91 .defaultValue{{Key(
"Shift_L")}},
92 .constrain{KeyListConstrain({KeyConstrainFlag::AllowModifierLess,
93 KeyConstrainFlag::AllowModifierOnly})},
95 "This key can only be used if current state is active, or is " 96 "deactivated with this key. For example, you have two input " 97 "methods: English as the inactive state, Pinyin as the active " 98 "state. It can be used to switch from Pinyin back to English, and " 99 "switch back to Pinyin again afterwards. If the initial state is " 100 "English will do nothing. This key can be configured to be some " 101 "simple single modifier key like Shift, so it can be used with " 102 "just a single key press, but won't be triggered by accident if " 103 "you never activate input method.")}}};
104 KeyListOption enumerateForwardKeys{
106 "EnumerateForwardKeys",
107 _(
"Enumerate Input Method Forward"),
109 KeyListConstrain({KeyConstrainFlag::AllowModifierLess,
110 KeyConstrainFlag::AllowModifierOnly})};
111 KeyListOption enumerateBackwardKeys{
113 "EnumerateBackwardKeys",
114 _(
"Enumerate Input Method Backward"),
116 KeyListConstrain({KeyConstrainFlag::AllowModifierLess,
117 KeyConstrainFlag::AllowModifierOnly})};
118 Option<bool> enumerateSkipFirst{
119 this,
"EnumerateSkipFirst",
120 _(
"Skip first input method while enumerating"),
false};
121 KeyListOption enumerateGroupForwardKeys{
123 "EnumerateGroupForwardKeys",
124 _(
"Enumerate Input Method Group Forward"),
125 {Key(
"Super+space")},
126 KeyListConstrain({KeyConstrainFlag::AllowModifierLess,
127 KeyConstrainFlag::AllowModifierOnly})};
128 KeyListOption enumerateGroupBackwardKeys{
130 "EnumerateGroupBackwardKeys",
131 _(
"Enumerate Input Method Group Backward"),
132 {Key(
"Super+Shift+space")},
133 KeyListConstrain({KeyConstrainFlag::AllowModifierLess,
134 KeyConstrainFlag::AllowModifierOnly})};
135 Option<KeyList, ListConstrain<KeyConstrain>, DefaultMarshaller<KeyList>,
140 .description{_(
"Fallback Previous page")},
141 .defaultValue{{Key(
"Up")}},
142 .constrain{{KeyConstrainFlag::AllowModifierLess}},
143 .annotation{_(
"Input methods may have different setup in their " 144 "own configuration. This is commonly used by " 145 "modules like clipboard or quickphrase.")},
148 Option<KeyList, ListConstrain<KeyConstrain>, DefaultMarshaller<KeyList>,
150 defaultNextPage{
this,
152 _(
"Fallback Next page"),
154 KeyListConstrain({KeyConstrainFlag::AllowModifierLess}),
156 {_(
"Input methods may have different setup in their " 157 "own configuration. This is commonly used by " 158 "modules like clipboard or quickphrase.")}};
159 KeyListOption defaultPrevCandidate{
162 _(
"Fallback Previous Candidate"),
164 KeyListConstrain({KeyConstrainFlag::AllowModifierLess})};
165 KeyListOption defaultNextCandidate{
168 _(
"Fallback Next Candidate"),
170 KeyListConstrain({KeyConstrainFlag::AllowModifierLess})};
171 KeyListOption togglePreedit{
this,
173 _(
"Toggle embedded preedit"),
174 {Key(
"Control+Alt+P")},
176 Option<int, IntConstrain, DefaultMarshaller<int>, ToolTipAnnotation>
177 modifierOnlyKeyTimeout{
179 "ModifierOnlyKeyTimeout",
180 _(
"Time limit in milliseconds for triggering modifier key " 183 IntConstrain{-1, 5000},
186 _(
"When using modifier only hotkey, the action may " 187 "only be triggered if the modifier key is released within " 188 "the timeout. -1 means there is no limit.")}};);
192 Option<bool> activeByDefault{
this,
"ActiveByDefault",
193 _(
"Activate input method by default")};
194 OptionWithAnnotation<PropertyPropagatePolicy,
195 PropertyPropagatePolicyI18NAnnotation>
196 resetStateWhenFocusIn{
this,
"resetStateWhenFocusIn",
197 _(
"Reset state on Focus In"),
198 PropertyPropagatePolicy::No};
199 OptionWithAnnotation<PropertyPropagatePolicy,
200 PropertyPropagatePolicyI18NAnnotation>
201 shareState{
this,
"ShareInputState", _(
"Share Input State"),
202 isAndroid() ? PropertyPropagatePolicy::All
203 : PropertyPropagatePolicy::No};
204 Option<bool> preeditEnabledByDefault{
this,
"PreeditEnabledByDefault",
205 _(
"Show preedit in application"),
207 Option<bool> showInputMethodInformation{
208 this,
"ShowInputMethodInformation",
209 _(
"Show Input Method Information when switch input method"),
true};
210 Option<bool> showInputMethodInformationWhenFocusIn{
211 this,
"showInputMethodInformationWhenFocusIn",
212 _(
"Show Input Method Information when changing focus"),
false};
213 Option<bool> compactInputMethodInformation{
214 this,
"CompactInputMethodInformation",
215 _(
"Show compact input method information"),
true};
216 Option<bool> showFirstInputMethodInformation{
217 this,
"ShowFirstInputMethodInformation",
218 _(
"Show first input method information"),
true};
219 Option<int, IntConstrain> defaultPageSize{
this,
"DefaultPageSize",
220 _(
"Default Candidates per page"),
221 5, IntConstrain(1, 10)};
222 ConditionalHidden<!hasKeyboard,
223 OptionWithAnnotation<bool, ToolTipAnnotation>>
227 _(
"Override XKB Option"),
231 {_(
"Override the XKB option from display server. It " 232 "will not affect the XKB option send to display, but just the " 233 "XKB options for custom XKB layout. This is a workaround when " 234 "there is no way to get the current XKB option from Wayland " 236 ConditionalHidden<!hasKeyboard, Option<std::string>> customXkbOption{
237 this,
"CustomXkbOption", _(
"Custom XKB Option"),
""};
238 HiddenOption<std::vector<std::string>> enabledAddons{
239 this,
"EnabledAddons",
"Force Enabled Addons"};
240 HiddenOption<std::vector<std::string>> disabledAddons{
241 this,
"DisabledAddons",
"Force Disabled Addons"};
242 HiddenOption<bool> preloadInputMethod{
243 this,
"PreloadInputMethod",
244 "Preload input method to be used by default",
true};
245 Option<bool> allowInputMethodForPassword{
246 this,
"AllowInputMethodForPassword",
247 _(
"Allow input method in the password field"),
false};
248 Option<bool> showPreeditForPassword{
249 this,
"ShowPreeditForPassword",
250 _(
"Show preedit text when typing password"),
false};
251 Option<int, IntConstrain, DefaultMarshaller<int>, ToolTipAnnotation>
254 _(
"Interval of saving user data in minutes"),
256 IntConstrain(0, 1440),
258 {_(
"If value is 0, the user data may only be saved when " 259 "fcitx quits (e.g. logout).")}};);
261 FCITX_CONFIGURATION(GlobalConfig,
262 Option<HotkeyConfig> hotkey{
this,
"Hotkey", _(
"Hotkey")};
263 Option<BehaviorConfig> behavior{
this,
"Behavior",
269 GlobalConfig::GlobalConfig() : d_ptr(std::make_unique<GlobalConfigPrivate>()) {}
271 GlobalConfig::~GlobalConfig() {}
273 void GlobalConfig::load(
const RawConfig &rawConfig,
bool partial) {
275 d->load(rawConfig, partial);
278 void GlobalConfig::save(
RawConfig &config)
const {
283 bool GlobalConfig::safeSave(
const std::string &path)
const {
285 return safeSaveAsIni(*d, path);
288 const KeyList &GlobalConfig::triggerKeys()
const {
290 return *d->hotkey->triggerKeys;
293 bool GlobalConfig::enumerateWithTriggerKeys()
const {
295 return *d->hotkey->enumerateWithTriggerKeys;
298 const KeyList &GlobalConfig::altTriggerKeys()
const {
300 return *d->hotkey->altTriggerKeys;
303 const KeyList &GlobalConfig::activateKeys()
const {
305 return *d->hotkey->activateKeys;
308 const KeyList &GlobalConfig::deactivateKeys()
const {
310 return d->hotkey->deactivateKeys.value();
315 return *d->hotkey->consumeRedundantActivateKeys;
318 const KeyList &GlobalConfig::enumerateForwardKeys()
const {
320 return d->hotkey->enumerateForwardKeys.value();
323 const KeyList &GlobalConfig::enumerateBackwardKeys()
const {
325 return d->hotkey->enumerateBackwardKeys.value();
328 bool GlobalConfig::enumerateSkipFirst()
const {
330 return *d->hotkey->enumerateSkipFirst;
333 const KeyList &GlobalConfig::enumerateGroupForwardKeys()
const {
335 return *d->hotkey->enumerateGroupForwardKeys;
338 const KeyList &GlobalConfig::enumerateGroupBackwardKeys()
const {
340 return *d->hotkey->enumerateGroupBackwardKeys;
343 const KeyList &GlobalConfig::togglePreeditKeys()
const {
345 return *d->hotkey->togglePreedit;
348 bool GlobalConfig::activeByDefault()
const {
350 return d->behavior->activeByDefault.value();
355 return d->behavior->resetStateWhenFocusIn.value();
358 bool GlobalConfig::showInputMethodInformation()
const {
360 return d->behavior->showInputMethodInformation.value();
363 bool GlobalConfig::showInputMethodInformationWhenFocusIn()
const {
365 return d->behavior->showInputMethodInformationWhenFocusIn.value();
368 bool GlobalConfig::compactInputMethodInformation()
const {
370 return d->behavior->compactInputMethodInformation.value();
373 bool GlobalConfig::showFirstInputMethodInformation()
const {
375 return d->behavior->showFirstInputMethodInformation.value();
378 PropertyPropagatePolicy GlobalConfig::shareInputState()
const {
380 return d->behavior->shareState.value();
383 bool GlobalConfig::preeditEnabledByDefault()
const {
385 return d->behavior->preeditEnabledByDefault.value();
388 const KeyList &GlobalConfig::defaultPrevPage()
const {
390 return d->hotkey->defaultPrevPage.value();
393 const KeyList &GlobalConfig::defaultNextPage()
const {
395 return d->hotkey->defaultNextPage.value();
398 const KeyList &GlobalConfig::defaultPrevCandidate()
const {
400 return d->hotkey->defaultPrevCandidate.value();
403 const KeyList &GlobalConfig::defaultNextCandidate()
const {
405 return d->hotkey->defaultNextCandidate.value();
408 int GlobalConfig::defaultPageSize()
const {
410 return d->behavior->defaultPageSize.value();
415 return d->behavior->overrideXkbOption.value();
420 return d->behavior->customXkbOption.value();
423 const std::vector<std::string> &GlobalConfig::enabledAddons()
const {
425 return *d->behavior->enabledAddons;
428 const std::vector<std::string> &GlobalConfig::disabledAddons()
const {
430 return *d->behavior->disabledAddons;
433 void GlobalConfig::setEnabledAddons(
const std::vector<std::string> &addons) {
435 d->behavior.mutableValue()->enabledAddons.setValue(addons);
438 void GlobalConfig::setDisabledAddons(
const std::vector<std::string> &addons) {
440 d->behavior.mutableValue()->disabledAddons.setValue(addons);
443 bool GlobalConfig::preloadInputMethod()
const {
445 return *d->behavior->preloadInputMethod;
450 return *d->behavior->allowInputMethodForPassword;
455 return *d->behavior->showPreeditForPassword;
460 return *d->behavior->autoSavePeriod;
465 return *d->hotkey->modifierOnlyKeyTimeout;
469 const auto timeout = modifierOnlyKeyTimeout();
473 return now(CLOCK_MONOTONIC) <=
474 (lastPressedTime +
static_cast<uint64_t
>(timeout) * 1000ULL);
int autoSavePeriod() const
Number of minutes that fcitx will automatically save user data.
const std::string & customXkbOption() const
The enforce the xkb option for custom xkb state.
A raw configuration tree that stores key-value pairs in a hierarchical structure. ...
int modifierOnlyKeyTimeout() const
Number of milliseconds that modifier only key can be triggered with key release.
bool showPreeditForPassword() const
Show preedit when typing in password field.
PropertyPropagatePolicy resetStateWhenFocusIn() const
Reset active state to the value of activeByDefault on Focus In.
bool consumeRedundantActivateKeys() const
Consume Activate/Deactivate keys even when the state does not change.
bool overrideXkbOption() const
Override the xkb option from display.
bool allowInputMethodForPassword() const
Allow use input method in password field.
bool checkModifierOnlyKeyTimeout(uint64_t lastPressedTime) const
Helper function to check whether the modifier only key should be triggered.
Class to represent a key.