The Road to Fcitx 5: 5. Good news for people who use multiple display server

A big refactor in fcitx 5 is to enable it to support for multiple display server. This is not limited to X11 + wayland, but it means you can use fcitx with multiple X11 server. While such functionality may have limitation about your layout settings, but still it will work for most of cases.

qdbus-qt5 org.fcitx.Fcitx5 /controller org.fcitx.Fcitx.Controller1.OpenX11Connection :1

The support for multiple X connection exists in the code for long time but it didn’t expose to the world till the commit today.

With a simple dbus call above, you can open an new X11 connection to display server :1. The classicui window, XIM, or client that uses dbus protocol in it will be able to use the “right” window in the display server. Though, kimpanel will not be able to enjoy this.

To test this funtionality, try it with some simply client:

Xephyr :1
qdbus-qt5 org.fcitx.Fcitx5 /controller org.fcitx.Fcitx.Controller1.OpenX11Connection :1
DISPLAY=:1 openbox
DISPLAy=:1 xterm

And you’ll find out that you can type in the xterm :P.

Posted in fcitx development | Tagged , , | Leave a comment

当你 Debug 一门过气语言生成的代码里面产生的 memory leak 时会发生什么 (a.k.a. 不要修改 vala 返回的 strv 的 length)

(会被写成 blog 发出来。)

直接上一段代码。

var array = elements.to_array ();
array.length = -1;
return "(" + string.joinv (" ", array) + ")";

提问,这段代码有什么问题?

它会生成这样的代码。

_tmp32_ = gee_collection_to_array ((GeeCollection*) _tmp30_, &_tmp31_);
array = _tmp32_;
array_length1 = _tmp31_;
_array_size_ = array_length1;
array_length1 = -1;
_tmp33_ = array_length1;
_tmp34_ = array;
_tmp34__length1 = array_length1;
_tmp35_ = _vala_g_strjoinv (" ", _tmp34_, _tmp34__length1);
_tmp36_ = _tmp35_;
_tmp37_ = g_strconcat ("(", _tmp36_, NULL);
_tmp38_ = _tmp37_;
_tmp39_ = g_strconcat (_tmp38_, ")", NULL);
_tmp40_ = _tmp39_;
_g_free0 (_tmp38_);
_g_free0 (_tmp36_);
result = _tmp40_;
array = (_vala_array_free (array, array_length1, (GDestroyNotify) g_free), NULL);
_g_object_unref0 (elements);
_g_free0 (_base);
_g_free0 (_tmp0_);
return result;

那么你再猜猜?给你点提示。

static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
    if ((array != NULL) && (destroy_func != NULL)) {
        int i;
        for (i = 0; i < array_length; i = i + 1) {
            if (((gpointer*) array)[i] != NULL) {
                destroy_func (((gpointer*) array)[i]);
            }
        }
    }
}


static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
    _vala_array_destroy (array, array_length, destroy_func);
    g_free (array);
}

´_>` strv 是一个不能改变大小的 array ……那么你改了它的大小……free 它的函数没法正常工作……然后就会造成 leak ……

Posted in Linux | Tagged , | 1 Comment

最近踩的一个关于 std::unique_ptr 的小坑。

简单来说就是这样一件事,std::unique_ptr 在析构途中调用了 .get() 会发生什么这样一个问题。

当然,你是不应该写出这样的代码的……但是有时候这样的行为可能并不是非常明显。所以就会导致问题…

一个 FreeBSD 上的人汇报了在 Linux 上没有的 crash。估计是 libc++ 和 libstdc++ 的行为差别。一个在析构途中就返回 null 了,一个还是返回原始的指针。

总之,小心避免写出这样的代码吧。

Posted in Linux | Tagged , | Leave a comment

Road to Fcitx 5: 4. Compatibility for different im modules.

I have been always care about the compatibility. Fcitx 5 will be able to type with either fcitx 4’s im module, or fcitx 5’s im module.

Fcitx 5’s im module will announce itself to accept both “fcitx5” and “fcitx”. Even if you did it wrong or forget to upgrade, application will still be able to pick up one of the fcitx im module. Even if it is the wrong one, the latest fcitx 4 im module is compatible with fcitx 5 server. There is no more excuse if you configure it wrong.

Even today, I just commit the code to even support ibus im module. So, when you start fcitx 5, it will automatically replace any existing ibus and initiate a shim dbus layer to provide ibus input context interface. So even your system is wrongly configured or forced by your desktop to use ibus im module, you should still be able to use fcitx anyway, as long as you didn’t forget to start it

.

Posted in fcitx development | Tagged , | Leave a comment

A case study: how to compile a Fcitx platforminputcontext plugin for a proprietary software that uses Qt 5

Due to the fact, that Qt 5 does not support XIM, the only way to type with fcitx under Qt is to use platforminputcontext plugin. The problem is that for some proprietary software like mathematica, it is impossible to use the system Qt plugin because the Qt version does not match (also the library path may not be correct).

If the proprietary software uses shared library version of Qt, it is still possible to get a special version of platforminputcontext plugin compiled. Though, they may have private modification on the Qt library, but it is highly likely the plugin interface is not changed so we can compile it with official Qt 5 source code but link to the private shared Qt library in the proprietary software. So here’s how I did it for mathematica.

First, you need to figure out which version of Qt that the software is using, this can be done easily by using some very hacky tool like strings / objdump since Qt encode it’s compilation info in Qt5Core library in string literals.

$ strings /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5CoreWRI.so.5 | grep "Qt 5"
Qt 5.6.2 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 4.8.2 20140120 (Red Hat 4.8.2-15))
This is the QtCore library version Qt 5.6.2 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 4.8.2 20140120 (Red Hat 4.8.2-15))
If that is not possible, in Qt 5 you must at least reimplement

Now we know it’s Qt 5.6.2. Then we can go to Qt’s offical site to download a official version of Qt 5.6.2. http://download.qt.io/official_releases/qt/5.6/5.6.2/ You can just use the QtCreator bundled with in it so it’ll be much easier to get compilation argument right.

Then, use QtCreator and choose import project from Git, https://github.com/fcitx/fcitx-qt5/ , and select the Qt that comes with your installation, instead of your system Qt 5. I managed to make fcitx-qt5 plugin standalone recently, so it will be really easy to get it compiled.

But remember, we need to link it against the mathematica’s Qt, instead of the Qt binary that we just installed.  The problem is, Qt relies on qmake to find the library path, and it is hard to make it find the mathematica’s Qt. In order to solve this problem, we can directly hack the final link command line generated by cmake.

First, cd to the right path. fcitx-qt5’s plugin does not rely on fcitx-qt5’s library any more, so it is possible to only compile and copy the plugin library. If you already compiled it with QtCreator, you need to run make clean first. So here’s what it looks like:

# Locate the build-fcitx-qt5-Desktop_Qt_5_6_2_GCC_64bit-Default directory.
cd platforminputcontext/
make clean
make VERBOSE=1

Pay attention to the last command, it may looks like this:

/usr/bin/c++ -fPIC -std=c++11 -Wall -Wl,--no-undefined -shared -o libfcitxplatforminputcontextplugin.so CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxinputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxqtdbustypes.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxwatcher.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qfcitxplatforminputcontext.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/main.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qtkey.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontext1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethodproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethod1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxplatforminputcontextplugin_autogen/moc_compilation.cpp.o -Wl,-rpath,/home/saber/Develop/build/Qt560/5.6/gcc_64/lib: /home/saber/Develop/build/Qt560/5.6/gcc_64/lib/libQt5Gui.so.5.6.2 /home/saber/Develop/build/Qt560/5.6/gcc_64/lib/libQt5DBus.so.5.6.2 /usr/lib/libxkbcommon.so /home/saber/Develop/build/Qt560/5.6/gcc_64/lib/libQt5Core.so.5.6.2

You’ll need to replace the Qt library with the one comes with mathematica.

/usr/bin/c++ -fPIC -std=c++11 -Wall -Wl,--no-undefined -shared -o libfcitxplatforminputcontextplugin.so CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxinputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxqtdbustypes.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxwatcher.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qfcitxplatforminputcontext.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/main.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qtkey.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontext1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethodproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethod1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxplatforminputcontextplugin_autogen/moc_compilation.cpp.o /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5CoreWRI.so.5 /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5DBusWRI.so.5 /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5GuiWRI.so.5 /usr/lib/libxkbcommon.so

Also remember to remove the rpath option from it. If the command finishes successfully, now you’ll get an usable fcitx plugin for mathematica. Then just copy it to the right directory:

sudo cp libfcitxplatforminputcontextplugin.so /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/Qt-Plugins/platforminputcontexts/

Then you can enjoy typing with fcitx in mathematica.

The directory path above need to be adjusted based on your own system.

Posted in fcitx development | Tagged , , | 1 Comment