世纪未解之谜之 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、找到太多字体

几年前一个 Emacs 用户研究许久之后,最终发现了因为找不到字体,才没办法使用的情况。

可能有人奇怪,为什么找到太多字体也会出问题?因为对于 X11 的协议来说,每条事件可以发送的字节是有限制的,而 Emacs 上恰恰因为找到了太多字体而且把这些一股脑全部都发送了,才导致输入法在创建连接阶段就已经失败无法继续进行。而这个字体的匹配过程,是会受到 LC_CTYPE 的影响的,当你设置成别的语言例如中文的时候,可能因为字体覆盖编码的原因,反而会让匹配的字体数量大大减少,而恰好满足了要求。

也正是这个副作用导致了为什么在有些人的系统上就一定要设置这个环境变量,而其他人的就不用,实质上是和你系统安装了某些字体有关而已……

本文主要感谢 Yichao Yu 的调试。顺便感谢他还写了个 Patch 给 emacs:https://debbugs.gnu.org/cgi/bugreport.cgi?bug=10867

This entry was posted in fcitx development and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.