How to use fcitx on Ubuntu 17.10

Since ubuntu moves to GNOME 3, there’s some difference if you want to use fcitx. It’s not hard to do, but need some manual tweak on user configurations.

Here is the instruction about how to use fcitx on a fresh installed ubuntu 17.10 system. Personally I just choose English as system language for this instruction, but it should make no difference.

So first of all, you will need to install fcitx and the input method you want anyway.

sudo apt-get install fcitx fcitx-mozc

Under GNOME the old im-config seems not working because GNOME only supports ibus and they don’t want any other input method related system to use it. We’ll need to set the environment variable manually because of that.

I used to recommend people use ~/.xprofile. but since this file is X only, I’d suggest to use .pam_environment file to set the variable.

On a freshly installed ubuntu 17.10, you will not have ~/.pam_environment file. So you can use

gedit ~/.pam_environment

to edit and create this file with following content.

XMODIFIERS DEFAULT=@im=fcitx
GTK_IM_MODULE DEFAULT=fcitx
QT_IM_MODULE DEFAULT=fcitx

Then, you’ll also need to add an autostart entry to start fcitx. Search “Startup applications Preferences” and add an new entry for fcitx.

After that, you’ll already be able to get Fcitx working. But I still recommend you to install this extension for better experience under GNOME. https://extensions.gnome.org/extension/261/kimpanel/. It also provides extra functionality on correctly setting keyboard layout under GNOME with fcitx. Otherwise any keyboard layout group change outside mutter will be reset to mutter’s internal value. (See https://bugzilla.gnome.org/show_bug.cgi?id=756543#c18 for more information)

Unfortunately, it’s hard to install gnome shell extension from browser in a default installation.

To use firefox you may follow the instruction on the website and install firefox extension. (I have no idea why Ubuntu doesn’t include this package and use firefox as default browser, probably this issue is worth a bug report.) You’ll also need to install

sudo apt-get install chrome-gnome-shell

Or you can use gnome’s browser

sudo apt-get install epiphany-browser

To install extension from browser. That are many other way to install gnome shell extensions so I’m not gonna to cover it all.

P. S.

My system does not gives me Wayland session for some reason, so I can’t test the GNOME wayland on Ubuntu 17.10. But just to let you know, as described in my last post, you may use fcitx on GNOME’s wayland session. Though, to get the input method window displayed at right location you currently will need to use fcitx’s master branch and use kimpanel extension.

Posted in fcitx development | Tagged , | Leave a comment

Gaps between Wayland and Fcitx (or all Input methods).

Though some people have no problem (or, only few problems) about using fcitx (to be more specifically version 4) with wayland, but the truth is there are still lots of problems left to be addressed.

The truth is, wayland is not yet ready for input method.

  1. Generic input method protocol is not widely adopted.
    In the old good X11 world, there is a protocol call XIM. No matter how bad it is, it widely used and adopted by nearly all applications. But as for wayland’s protocol “text-input”, the current situation is:
    – Gtk3 doesn’t support it.
    – Qt5 support a not-upstreamed version 2.
    – EFL / weston support the official version in wayland-protocols.
    – SDL2 doesn’t support it.
    – Weston’s reference client side implementation has critical bug.
    What does this mean? This means even you’re using wayland + (GNOME/KDE) for now, you’re still using the old im module via DBus.
  2. The generic input method protocol is bad.
    It is weird that in wayland world, key repetition is a task of client. But the problem is, it even becomes a work for input method. Fcitx 5 for now is the only implementation handles key-repetition correctly. But I don’t even care about this because I don’t even have a real application to test this feature. (You need a patched version for weston-editor to play with it).Also, the wayland input context will be destroyed once it get unfocused, which makes it unable for input method server to track different window and keep different input state for different window (e.g. different window + different im will need this feature) .
  3. The window positioning issue.
    In Wayland world, there’s no way for a non-compositor window to place the window by abstract coordinates (x, y). Also there is no way for a non-compositor window to know about its own location. But for input method, you need to display a window at the position of cursor. The “input-method” protocol in wayland allows you to assign a surface as “input panel”, and the compositor will move it for you.
    This means: when you’re using im module via dbus or typing in a Xwayland window with XIM, it can’t make use of this feature. But you may say, under plasma wayland, or gnome-shell I didn’t see any problem.This is because:
    – GNOME shell is the compositor, it can do hacky things to move the input method window around and make use of compositor feature. Currently gnome-shell’s ibus extension and https://github.com/wengxt/kimpanel-for-gnome-shell/ (you can use it with fcitx) use this method.
    – For Plasma, the plasma shell window occupies the whole screen, which makes kimpanel able to locate its window freely with absolute coordinates.Except these two specific environment (no, weston will not work), input method server will not be able to move the input method window freely.
  4. Keyboard layout management
    This is somewhat less important for now, because of the issue listed above. Input method server (fcitx or ibus) are trying to managing keyboard layout, but there’s no common interface to do this.

Due to the issues above, I do not recommend to use wayland if you need input method. You can try it today, but you may find it working or not working. Also, these issues also largely extinguished my passion about working on wayland. Since for now there are still a lot of works going on with fcitx 5 and libime, my focus are mostly on them instead of making fcitx working on wayland.

But no need to give up too soon, as for the solution, It seems that KWin wants to run input method inside compositor process and this may solve a large portion of problem listed above, because: 1. kwin is compositor, it knows everything about a window, 2. kwin on wayland will control keyboard layout, 3. no “input-method” protocol is needed. Fcitx 5 also contains work to make fcitx run as a library more easily.

Right now my work replacing fcitx 4’s pinyin and table with libime is  near completion. Let’s see how it goes from here.

Posted in fcitx development | Tagged , , , | 3 Comments

最近的一个 Linux Intel 驱动问题和 Workaround

老实说一般我都不愿意写这种文章。因为这种文章基本上都是很有时效性的。但毕竟这个问题已经困扰了我好几个月,所以还是打算记录一下方便同样遇到问题的人。

具体表现是,开机正常,使用正常,但是如果放久了就会黑屏再也起不来。这时还能 ssh 进去,但是从 ssh 重启很大可能会等待很久。上游的 bug report 我也不好分辨到底是哪个,就随便列出几个我觉得相关的。

https://bugs.freedesktop.org/show_bug.cgi?id=102224
https://bugs.freedesktop.org/show_bug.cgi?id=102853

那么最后我的解决方案是什么呢……总之也是在某个 report 里面看到有人提到的方法。

在 /etc/modprobe.d/90-i915.conf 里面写上

options i915 enable_guc_loading=1 enable_guc_submission=1 disable_power_well=0

总之我加上这个参数之后好久都没有出过问题了。

顺带一提我正在使用的内核版本是 4.13.0 但是这个问题至少困扰我了好久好久大概从 4.9 之后升级了 BIOS 开始……

Posted in Linux | Tagged , , , | Leave a comment

一个关于 Pimpl 的小技巧

使用 Pimpl 很多时候是必须的,ABI 兼容的时候基本都要靠它。在 C++ 11 当中,通过 default member initializer 可以实现很多有趣的效果,加上宏的话很多时候可以利用来实现 Metadata 的效果,例如:

#define PROPERTY(NAME) \
    Property NAME{this, #NAME};

class Registry {
    friend class Property;
    public:
        int& getValueByName(const std::string &name) {
            return *values_[name];
        }
    
    protected:
        void registerValue(const std::string name, int* value) {
            values_[name] = value;
        }
        std::unordered_map<std::string, int*> values_;
};


class Property {
public:
    Property(Registry* r, const std::string& name) {
        r->registerValue(name, &value_);
    }
    
    operator int() { return value_; }
    Property& operator=(int v) { value_ = v; return *this; }
    
private:
    int value_;
};

class MyRegistry : public Registry {
public:
    PROPERTY(a);
    PROPERTY(b);
};

int main()
{
    MyRegistry r;
    r.getValueByName("a") = 1;
    r.b = 2;
    return r.a + r.getValueByName("b");
}

但是实际上这还是需要定义新的 member,如果将来有了新的 member 就没法保证 Binary compatibility 了,假设我们要把 MyRegistry 转变成 Pimpl 怎么办呢?简单实现一下的话就会变成这样:

class MyRegistryPrivate {
    Property a{???, "a"};
};

那么 ??? 处传什么才好呢?

你可能会想到把 MyRegistry 的 pointer 传给 Pimpl 不就行了吗?但是不要忘了,我们还依旧希望通过 default member initializer 的形式来定义。传过来的参数之后即使直接去 initialize,也是在 default member initializer 之后才进行了。也就是说这样是不行的:

class MyRegistryPrivate {
    public:
        MyRegistryPrivate(MyRegistry *q) : q_ptr(q) {}

        MyRegistry *q_ptr;
        Property a{q_ptr, "a"};
};

也就是说要保证在更早的时候初始化 q_ptr,可以用一层继承来保证这点。

template
class QPtrInit {
public:
    QPtrInit(T *q) : q_ptr(q) { }
    
protected:
    T* q_ptr;
};

class MyRegistryPrivate;

#define PROPERTY_PRIVATE(NAME) \
    Property NAME{q_ptr, #NAME};

class MyRegistryPrivate : QPtrInit {
    public:
        MyRegistryPrivate(MyRegistry* q) : QPtrInit(q) {}
        
        PROPERTY_PRIVATE(a);
        PROPERTY_PRIVATE(b);
};

完整例子参见:http://cpp.sh/4bhvh

Posted in Linux | Tagged , , | Leave a comment

Shell script for Google TTS on Plasma desktop

My wife has extreme dry eye condition, so she want to avoid looking at the screen as much as possible. She asked me for a solution for Text-to-Speech on linux desktop.

Basically her requirement is to press a key and read out what she selects. I check jovie, but that’s somehow discontinued and the only speech-dispatcher backend available on my distro is espeak, whose voice quality is poor comparing to any modern solution on the desktop.

So I decided to check if there’s any available solution on internet and see if there’s a solution that using Google translate’s TTS service.

So far I found a script from http://elinux.org/RPi_Text_to_Speech_(Speech_Synthesis)#Google_Text_to_Speech

Which I adjusted a little for my usecase:

#!/bin/bash

TEXT=$(xsel)

say() { local IFS=+;/usr/bin/mplayer -really-quiet -noconsolecontrols "http://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=$*&tl=en"; }
say $TEXT

I added xsel for reading string from primary selection, which is exactly what she’s asking for. And then I use plasma’s convenient custom global shortcut to bind a key to this script. Then you can enjoy the google tts with a single key press.

Posted in KDE | Tagged | 2 Comments