Tag Archives: xim
世纪未解之谜之 Emacs 为什么要设置 LC_CTYPE 才能用输入法终于
在 Linux 上用 Emacs 和输入法的人可能都曾经有这样的疑惑,为什么只有 emacs 非常奇怪经常要额外设置一个 LC_CTYPE 才能正常使用输入法。很多年以前,我也一直不明白,直到最近 LibX11 的一个 bug 让我们有机会找到了…Emacs 不能用输入法的真正原因。 首先声明,并不是 Emacs 对这个环境变量有任何的判断。设置它,只是触发了一个副作用让 Emacs 能够正常工作。而这个真实原因的线索其实在几年前就已经被发现了并且写到了 Fcitx Wiki 的 FAQ 上,但是一直没有被联系起来。 首先要说 XIM。XIM 这个协议里面其实有很多过时的部分,过时的意思主要是指,实际上在今天完全没有人使用了的部分,但是因为 LibX11 的实现和 XIM 高度绑定,所以不得不依然使用的部分。其中一个就是需要设置一个字体。这个字体的本意,大概只是为了让输入法知道程序在用什么字体,可能让输入法可以选择配合窗口的字体来绘制输入框。XIM 的协议,主要是通过 X11 的 ClientMessage 来实现的,发送字体的部分,是传递一大堆字体的名字列表过去。但是好巧不巧,Emacs 判断这部分关于字体的代码可能会出现很多不同的问题。 可能的问题包括: 1、找不到字体2、找到太多字体 几年前一个 … Continue reading
输入法环境变量的故事
有时候我想想,我是不是应该写一些比较普及的文档(你懂得,我特意纠结了一下措辞)。 那么这次先来介绍一下关于输入法的环境变量配置问题: 在远古时代,世界一片混沌,那时世界上还没有 X 窗口下的输入法支持。 神说,要有输入法,于是就有了 XIM 协议。 这个时代(当然还有个几个XIM协议的版本更新),需要设置的环境变量有 XMODIFIERS=”@im=imname” 比较现代的程序的话,是不用纠结imname这个值的,输入法自己会自己也检测一把这个值,然后启动xim的时候也把自己变成这个值。印象中一定要这个环境变量的程序有xterm。 然后XIM有诸多缺点,至少在输入法程序关闭(不一定是死掉)的时候,可能让程序freeze,或者崩溃。 于是神看到XIM是坏的,授意GTK和QT自己做自己的IM Module。 从此天下大乱。 先来看 Gtk 这边,假设没有环境变量,Gtk是读取一些配置文件里面记录的im module的。每个im module都有指定语言,也就是按环境的语言设置匹配。这里来第一个常见问题:英语环境为什么默认不能用输入法而要纠结 LC_CTYPE=”zh_CN.UTF-8″。就是为了让 Gtk 的匹配能够匹配中文的IM Module。当然我个人是反对这种配置的,因为其实只要 GTK_IM_MODULE 足以。世界上据我所知唯一一个奇葩程序一定要这么设置那就是emacs。(因为作为gtk界面的emacs其实是用XIM协议……鬼知道里面hardcode了啥) 第二个常见问题,为什么卸载了ibus就可以用 fcitx,那是因为系统中同时有两个zh的im module(其实是三个,还包括了xim),你不设置环境变量的话,那就会让gtk自己选择了,这个顺序似乎也不确定,如果选到ibus但你用fcitx,或者选到fcitx你用ibus,都会导致你输入法不能正常使用。 设置了GTK_IM_MODULE之后呢?假设匹配到对应的im module,就会使用对应的im module,假设没匹配到,那就返回之前的没有设置的情况。 LC_CTYPE和设置*_IM_MODULE两种方式我偏好后者。 这里还有个很脑残的问题,GTK一定会去读取 /etc/gtk-2.0/gtk.immodules (按发行版,和cpu架构,以及gtk版本可能不同)里面记录的im module,尽管gtk-query-immodules-2.0和gtk-query-immodules-3.0是可以自己查询的。所以打包者必须自己在安装后脚本内更新这些文件。可能当初Gtk想做缓存……不过现在这年头不缓存也没啥大不了的了。 回到 Qt 这边,情况稍好,首先挑选规则还是如之前所述,按语言。但如果没有环境变量QT_IM_MODUE的干预,这个可以通过 … Continue reading