Author Archives: csslayer

Fcitx 5 开发(三)如何调试输入法,先有鸡还是先有蛋

调试输入法,和写别的程序其实没有本质的区别,常见的办法也就是 GDB 和输出日志。但它特别的地方主要在于,你用来调试输入的程序也是输入法的客户端之一,在调试输入法的时候,如果不进行一些特别的操作,将会导致你调试用的终端 Freeze(把按键发送给了输入法,却因为程序 GDB 暂停无法获得响应导致 Freeze),也就是标题所说的先有鸡还是先有蛋的问题。 当然,要解决这个问题其实也简单,就是让你的终端不用输入法就行了。这里有几个点需要注意,常见桌面环境的终端一般是单实例,你即使启动一个新的窗口也是同一个进程,并不是重新启动一个进程。所以一般我个人会选择使用另外的终端程序。这是从终端程序禁止输入法方面来说。反过来,也可以通过命令行参数禁用 Fcitx 的前端。来阻止 Fcitx 和对应类型的程序进行通信。 先说说怎么启动一个无法使用输入法的终端。如果是 XIM 的终端,例如 xterm,alacritty,就直接用 XMODIFIERS=@im=none xterm 这样的方式启动,启动之后,在终端里面直接启动新的 fcitx 的话,就需要注意要在终端里面重新恢复 XMODIFIERS 的值为一般的值。因为根据 XMODIFIERS 的处理机制,Fcitx 会根据它启动时的 XMODIFIERS 设置对应的值。如果不进行设置的话,当前的这个终端自然也反而会可以和 Fcitx 通信了。如果是 Gtk 程序,可以设置 GTK_IM_MODULE=gtk-im-context-simple ,如果是 Qt 5程序,可以设置为 QT_IM_MODULE=compose 。 如果想要从 Fcitx … Continue reading

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

Fcitx 5 开发(二)一个按键事件的后半生

当按键被 Fcitx 的前端接收到之后,首先它需要找到对应的输入上下文,然后创建对应的按键事件结构: https://github.com/fcitx/fcitx5/blob/c492be884540b55ee590d0e3312c4889c8bf4300/src/lib/fcitx/event.h#L242 首先对于一个按键来说,我们先要区分和按键相关的好几个不同的值的含义:Code,State,Symbol。Code 表达的是这个按键对应的物理按键,例如键盘上的 A,不论你在什么情况下按 A(Caps Lock / Shift),产生的 Code 是一样的。State,表示了按键发生时键盘的状态,包括了锁定键的状态,比如 Num Lock 和 Caps Lock,还有各种修饰键(Modifier)的状态是否被按下。当然,对于 32 个 Bit 来说,键盘并没有那么多的按键,因此有一些位在 Fcitx 中也被挪作他用,例如 https://github.com/fcitx/fcitx5/blob/c492be884540b55ee590d0e3312c4889c8bf4300/src/lib/fcitx-utils/keysym.h#L51 这个就是新加入的按键是否是重复键的。 Symbol 则是表达了经过键盘布局转换之后得到的符号,一般来说,输入法的逻辑是直接和 Symbol 打交道的,而不关心从 Code 到 Symbol 之间的转换。Fcitx 的 Symbol 对应的数值是采用和 X11 Symbol 一样的值来简化判断,这样在大部分情况下都不需要重新进行映射。 … Continue reading

Posted in fcitx development | Tagged , | Leave a comment

Fcitx 5 开发(一)一个按键事件的前半生:由程序到输入法

因为觉得有必要趁着 Fcitx 5 发布的功夫,决定写一系列的关于如何开发 Fcitx 5 相关内容的文档,之后会更新到 Wiki 上。 要理解输入法是如何工作的,首先要了解的是程序究竟是如何与输入法进行交互的。而这一部分的内容,也与一个常见问题相关:为什么我在 A 程序里面无法使用输入法? Fcitx 的基本架构是客户端/服务器架构,客户端,在 Fcitx 里面对应的词是“输入上下文(Input Context)”,具体究竟对应程序中的哪一个实体,是并没有明确规定的。一般来说,可能是对应程序的一个窗口。而具体对应什么,是取决于程序自己的实现,也就是“程序认为”哪些部分应当作为同一个上下文来处理。虽然,在实践当中一般并不会有程序做到如此的细化。 当一个程序不能用输入法的时候,一般最常见的情况就是这个程序并没有采用正确的方式和输入法进行通信。 那么,目前在 Linux 下到底有多少种不同的客户端通信方式呢?看看源码中 frontend 目录下有多少就知道了。 这里我们也详细说明一下各个目录的情况: 1、xim,最古老的基于 X11 的输入法协议。在 X11 下理论上是通用的,实现由 Xlib 完成。和 Xlib 的事件处理结合非常紧密,采用了一种直接原生和 Xlib 按键转化字符串的方式来实现,而不是非常直接的有回调来传递输入法想要程序进行的操作。Xlib 的实现里面非常多的操作都是实现成同步而且并没有错误处理,这也导致了一旦输入法退出,程序如果此时在进行一个同步操作,就会直接冻结。而这部分代码过于古老基本上处于没人会去改的状态,其中非常古老的缺陷之一就是光标跟随和嵌入预编辑文本无法共存,尽管从协议的角度来说,并没有什么道理阻止这个功能,但就是几年尽管有 Patch 都没有合并的状态。 XIM 允许多个输入法注册在 … Continue reading

Posted in fcitx development | 1 Comment

Client Side Input panel for Fcitx 5

(English version is at the end of this post.) 输入框的定位相关的问题其实很复杂,过去 Fcitx 总是自己绘制相关的窗口。X11 这个办法还好使,但是其他情况可能就没这么好使了。让客户端绘制窗口的想法其实比 Fcitx 5 要早得多,最早是为了 fbterm 而增加的支持。 显然 fbterm 没法利用任何来自显示管理器的界面,所以它需要自己绘制它自己的界面。那会儿我添加了一个很简单的实现来支持这个功能。 为了正确显示界面需要支持以下功能: 窗口显示在光标的位置 窗口不能移出屏幕 在 wayland 里,和 X 最大的区别就是不知道窗口的位置,所以不得不使用特别的方法来支持。 用 wayland 的输入法协议的话,它确实是支持将某个窗口标记为输入法窗口并让混成器帮你进行定位,但是需要程序自己先使用 wayland 的输入法协议,混成器也要支持这个协议。目前这两部分的支持并不好。 或者让窗口传送一个相对坐标,然后让混成器帮忙移动窗口。gnome wayland + kimpanel 的扩展就是这样进行定位的,因为 kimpanel … Continue reading

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

构建一个给 WPS 用的 fcitx im module

WPS 处于许可证的考虑,里面自带的 fcitx 的 im module 是由 WPS 的开发自己写的。但是这就有一个问题了,他们对于跟随 fcitx 上游的变化可以说是几乎没有。在 Fcitx 4 已经加入了对于 flatpak / fcitx 5 的支持之后他们并没有做出对应的改变,导致了现在的很多问题。 在过去的这篇也曾经写到了,如何构建一个给闭源 Qt 程序用的模块。 我不知道过去有没有人干过这样的事情,但我们现在就来做这么一趟。 首先观察 WPS 使用的 Qt 版本 $ ls /usr/lib/office6/libQtCore.so -l                        lrwxrwxrwx 1 root root 18  1月 15 … Continue reading

Posted in fcitx development | 1 Comment