为什么Gtk程序总爱给我找麻烦

http://code.google.com/p/fcitx/issues/detail?id=528

这是起因,当然铺垫还有很多,我就懒得说了。

Glib 使用 C 实现 signal 的一个缺陷。具体来讲就是这么回事,在glib里面,很多时候处理signal,为了通用,以及能够使用同一个函数作为signal_connect,于是所有的函数指针都会转化为 (void*)(G_CALLBACK)

    g_signal_connect(context->slave,
                     "commit",
                     G_CALLBACK(_slave_commit_cb),
                     context);

那么问题在于,缺少对 callback 函数的合法性验证,可能会出现各种潜在的问题。在不是有意为之的前提下,程序员仍然会更容易犯错误。

拿pidgin里面的一个问题举例,pidgin的状态输入框,不知道有没有人注意到,在里面用backspace和输入法是很不正常的,会同时删掉输入法这边和pidgin里面两个字符。

为什么?明显是一个按键事件被搞了两次。

我的一个朋友花了一些时间去debug这个问题:

Finally I traced it down to the problem.
 我本来是看见这么一行:
g_signal_connect(G_OBJECT(gtkconv->entry), "key-release-event",
                 G_CALLBACK(gtk_conv_key_press_cb), NULL);

去掉就没事了。
这个函数如下:
static void gtk_conv_key_press_cb(GtkWidget *tv, GdkEventKey *event,
gpointer data)
{
       gboolean togglemenus = purple_prefs_get_bool(PREF_TOGGLE_MENUS);
       gboolean enabled = purple_prefs_get_bool(PREF_ENABLED);

       if(enabled && togglemenus){
               if(event->state & GDK_CONTROL_MASK){
                       if(event->keyval == GDK_F11){
                               ToggleConvMenu();
                       }
               }
       }
}

好吧,看起来很正常吗?编译器都会很happy的连warning都没有就run过去了。

但是实际上key-release-event的返回值是gboolean。

于是人民群众喜闻乐见的输入法bug来了。这个函数本来应当提供返回值,但是没有提供,在c里面这个指针在注册的时候是没有经过类型检查的,于是出现了一个本不应当注册的函数。但是在调用的时候,其实是预留了返回值的位置(由编译器),所以不会出现导致crash的错误,但是依然会导致这个返回值出于未定义状态。

好吧,那么当年scim和ibus为了从源头干掉这些中低水平程序员问题,于是用了gtk_key_snooper,使得所有gtk程序的按键事件先从im module这边走一圈,然后才会丢回给程序。于是今天我也给fcitx加了key snooper(要不然真没法活了),我本来对于程序和输入法之间的观点是,程序应该保持行为正常,输入法尽量不干预,即使我在最初实现fcitx的gtk的im module的时候可以实现它,我还是没去用,不过gtk程序们抱歉了,如果你们当中连gedit这种货色都敢来惹我,我没理由不相信类似情况是在gtk程序中普遍存在的,是你们先来惹我的。

但输入法本来提供的接口只有imcontext那些,这也就是感谢上苍还肯给输入法个活路。但是一个bug即使workaround掉了,还是一个bug。如同药片裹了糖衣,它还是药片,只不过……嗯,没那么难吃罢了。

Posted in fcitx development | 7 Comments

M17N & Mozc

Compiling Mozc is a really just as hard as Chromimum, so I don’t recommend to try it now, I haven’t finished doing all the build system related work for Mozc.

fcitx-m17n is quite a lot simple, just use the regular way to compile it:

mkdir build
cd build;
cmake .. -DCMAKE_INSTALL_PREFIX=`fcitx4-config --prefix`
make
sudo make install

They are both on github:

http://github.com/fcitx/fcitx-m17n

http://github.com/fcitx/mozc (a pseudo fork, for the reason, check the read me.)

You will need fcitx from git.

Have fun!

Posted in fcitx development | Tagged , , | 2 Comments

Just become a proud Chakra developer!

不需要内容…… 🙂

Posted in 日志 | Tagged , | 4 Comments

Nginx server_name 后边域名是用空格分隔的啊分隔的啊分隔的啊!

无内容。

Posted in Linux | Tagged | 2 Comments

VLC 播放 HTTPS Stream

总之,据说vlc是少有的可以播放https stream的播放器。

但其实还蛮坑爹的……不知为何vlc是识别系统的ssl证书的(至少在我的arch上是的)。

以下方法仅在arch上测试过。

mkdir -p ~/.local/share/vlc/ssl
cd ~/.local/share/vlc/ssl
ln -s /usr/share/ca-certificates certs

于是就是这样了。也不用像某些网站一样导出根证书什么的再复制,直接用系统的证书就好啦。(除非你想自己签名个不合法的)不过这年头反正ssl证书有startssl这种免费证书存在。

我折腾这是为啥呢?因为OwnCloud的Ampache流播放音乐之前HTTPS一直不行,后来才发现是这个原因。于是只要你使用phonon-vlc的话,OwnCloud + HTTPS + Ampache + Amarok 是不会有问题的了。

P.S.

我发现 gstreamer 也可以……我到底是在闹哪样……

Posted in Linux | Tagged , | 6 Comments