How Fcitx works
What is Fcitx?
Fcitx is a program that let you communicate with other program with input device and help you typing text. So you don't need to restrict your idea that you must use fcitx to type some specific language, no, it can go far away from that. Everything that is related to typing text can make use of fcitx framework.
Due to keyboard is still a irreplaceable part of nowadays computer/device, so the workflow of Fcitx is still key-centric. It can be separated into seven phase, Pre-Filter, Do-Input, Get-Candidate, Paging, Post-Filter, and Hotkey, KeyBlocker. It works like a waterfall, that key goes in from Pre-Filter, and goes out from Hotkey. It looks quite complicated right? Let us start from some example.
If you want to implement an input method, the things you need to care about is the "Do-Input" Phase and "Get-Candidate" Phase, usually, we put code that are related to update UI into "Get-Candidate". For input methods in Fcitx, we require input method to return all the candidate at once. Some other framework maybe just return by page, fcitx didn't prevent that, but return all candidate at once have some obvious benefit. If we doing so, we don't need to keep every page for the same size, we can split into different page by the "length" of candidate. This would be especially important if you are working a small device (phone, for instance).
Some input methods mean to manage all the key, in that case, you only need to implement Do-Input, and leave Get-Candiate empty. Some other input method may want to cooperate with other module. For example, you now have a Pinyin library, but that library can only convert pinyin to Hanzi, so you might want to use Punctuation module of Fcitx. Make sure you know what module you want to cooperate with.
Temporary input mode
If you want to implement something global, independent with input method, for example, press "Ctrl+Shift+Alt+U" and type hexcode to input Unicode character, then what you want to do is something we called "Temporary input mode". It works just like a input method, but it only provides limited function for special use. In this case, we need to care about "Pre-Filter". As you can see, "Pre-Filter" can filter the key before it goes into real input method, so we simply process everything here.
Translator: Translate what you type with input method
Here we introduce two different filter, commit filter, and output filter. Commit filter only works when you really commit string to program, output filter will also work on all "visible" string in input box. Fullwidth string uses the commit-filter, to convert all string into full width form, while Chttrans use both commit filter and output filter.
Candidate Modifier: Modify the candidates
Sometimes, a addon can be also used to append some extra candidates. Usually, the reason for why this is not implement inside an input method, is result more or less order diagnostic. For example, when you're typing Pinyin, another addon can check whether your Pinyin is really an English word or not, if so add an additional candidate to list.
Implement such addon can reduce duplicate code among different input method, and bring more consistency between similar input method.
Categorize some built-in addon in Fcitx
|Autoeng||Temporary input mode|
|Clipboard||Temporary input mode|
|IMSelector||Temporary input mode|
|PinyinEnhance||Candidate Modifier and Temporary input mode|
|QuickPhrase||Temporary input mode|
|Unicode||Temporary input mode|
Some philosophy and rule of Fcitx
Think before you make any choice. Change/Choice should come after reason, and think more how will they affect other user. For example:
1. Add a new hotkey. Ask yourself, is this easy to press? If not, is it use frequently? Is it occupied by popular application? Usually, if a function is only for advanced user, we don't bother if combination is hard to press. And if you really want to introduce "meta" into combination, think about what if keyboard don't have that key.
2. Add candidate to temporary input mode. Ask yourself, is the candidate too long that will make input window outside the screen (This is what happened to Unicode)? Is the digit key designed to choose the candidate? If so, do you need digit as input string? If answer is yes again, you need to find a way to resolve such conflicts.
Face the reality
The input method world in Linux is far from perfect, especially for those faulty application.
Even some simple thing can be hard to judge, for example, enable "On the spot" for xim or not? Now fcitx have gtk/qt im module, so we expect user to install them right?
Here is my reason for not enable it.
1. Fcitx used to have xim only, user configure gtk/qt to use xim, those configuration can't be changed automatically.
2. Enable "On the spot" will break the cursor following for almost all non-gtk/qt application except opera. Or, opera is the only application that can be benefit from this. I don't want to risk break gtk/qt application but just make it work for opera.
And after I make this decision, month later, I found it make life easier when WPS for Linux comes out. Due to technology limitation, WPS can't use system qt im module but only xim, so fcitx can work with cursor following under WPS comparing with others.
Keep everything loose-coupled, but don't be constrained by dependency
Fcitx use some very special way to keep addon and addon is loose coupled. Fcitx provides a standard way to call function inside another different addon.
As we all know, there are some people, who REALLY care about reduce the dependency, you can leave them a way, but keep in mind that user who use full featured fcitx is who we target for.
Fcitx is never afraid of use latest technology (DBus, GIR, Qt, Gtk3), but don't depend on something too hardly. And do some research on which version of popular distribution can satisfy the dependencies (Especially, we consider CentOS, Debian, Ubuntu here, since they are usually out of date).
Be backward compatible
There're times that fcitx ignored some kinds of backward compatibility (4.0 -> 4.1 skin change, 3.6 -> 4.0 data format and configuration layout change), but since 4.2 we finally reach a level that we don't have much limitation, and things are well organized, there is no more excuse can be taken for not keep the backward compatibility.