Setup Fcitx 5 on Linux (Video)

Recently I started to make some video with detailed step on how to setup Fcitx 5 on different distribution.

Helps are also welcome if you want to make an instruction for the distribution that you use.

Fedora/KDE: https://www.youtube.com/watch?v=FwqTtGEN4vQ (Vocal by me in English)

Archlinux: https://www.youtube.com/watch?v=8XDmLr6wb4M (No voice, English/Chinese subtitled)

Posted in 日志 | 1 Comment

一个小玩具:fcitx5-tmux

就是觉得这个应该还挺好玩的。一开始其实还想着靠着写这个练习一下 Rust,结果就发现这个文档丰富程度实在是感人,特别是你用一些很少人用的库的时候,觉得还是算了。C++糊一下也就200多行。

原理很简单,就是通过手工执行 bind-key 把 tmux (几乎)所有的按键都绑定成一个 dbus 调用命令,然后交给一个代理的 dbus 服务和 fcitx 进行交互。把处理的结果再利用 send-key 发送回来。

现实来说还是有很多不太理想的地方,例如Control 的组合键就无法区分大小写,还有一些其他的小问题,所以总之是当作一个玩具来写。

代码地址:https://github.com/wengxt/fcitx5-tmux

梦回CCDOS

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

Use Plasma 5.24 to type in Alacritty (Or any other text-input-v3 client) with Fcitx 5 on Wayland

Relationship between the input method server and applications under Fcitx5+KWin/Wayland

With the latest release of Plasma 5.24, the native wayland input method support in KWin is improved to support non-virtual keyboard input method like Fcitx 5. (There are lots of issues if you try to use zwp_input_method_v1 in 5.23).

This leads to a outcome that non-Gtk/Qt application using text-input-v3 can be used flawlessly under KWin Wayland. Though, there is some small step that you’ll need to follow.

First of all, I suggest you have most up-to-date Plasma 5.24 and Fcitx 5.0.14. I believe the distribution that picks up Plasma 5.24 should also have up-to-date Fcitx 5.

Next, you’ll need to make KWin Wayland to launch Fcitx 5. This is required because only the privileged client is allowed to talk to KWin on input method protocol. KWin will send a socket file descriptor to the input method and input method service need to use this socket to connect to KWin.

Thanks to a simple KCM, which is accessible from systemettings -> Virtual keyboard (Naming of the KCM is not so good, because it was designed for mobile phone to launch maliit initially.)

From there, just select Fcitx 5. This requires you to have up-to-date Fcitx 5 to make it show up in this KCM, because it requires a special new field in the Fcitx 5 desktop file.

Although kwin will launch input method in a pretty early stage, but there might still be some race condition if there is another mechanism (Like XDG autostart) to launch Fcitx 5. You can try to re-login to see if if works, if not, you may want to disable Fcitx 5’s own XDG autostart or what ever mechanism you’re using to launch Fcitx 5.

Theoretically you don’t need to re-login, KWin can reload it immediately after you apply the setting in systemsettings. I would just re-login to make sure everything it properly launched, then you should be good to go.

Hello world from Chinese Pinyin!

Should I keep setting GTK_IM_MODULE / QT_IM_MODULE / XMODIFIERS?

  1. QT_IM_MODULE
    Qt has text-input-v2 support which can be used if QT_IM_MODULE is empty, but it has some small issue regarding the preedit. Also, with current version of wayland input method protocol, there can be only one global input context for wayland. So right now it can be a problem if you want to use the “per-application” input state supported by Fcitx 5. But using Qt’s text-input protocol has one benefit, is that visually there won’t be blinking for input window.
  2. GTK_IM_MODULE
    Gtk has text-input-v3 support, but it’s preedit is poorly styled with bold font for highlight. Also, its surrounding text support is poorly implemented. So for now, using GTK_IM_MODULE=fcitx might still be good option if you want to have all Fcitx features.
  3. XMODIFIERS
    It’s required to support XWayland.
Posted in Linux | Tagged , , , , , , | 3 Comments

开发输入法是一种妥协的艺术

很久很久以前,我还没有在用 Linux 的那个时候,那会儿还在用 Windows 上的搜狗输入法。有时候经常就会好奇一件事,为什么输入法的更新日志里,经常会有「修复和XXX程序的兼容性」,「修复和YYY程序的兼容性」,难道他们不应该采用一套统一的接口吗?

几年以后当我开始在 Linux 下开发输入法之后,我终于了解了一切……

有些东西其实还是颇为为难的,我就来说一下曾经处理过的bug(有些解决,有些未解决,或者难以解决)。

1、LibreOffice 的 crash

简单来说原理就是在某个 Qt 调用 IM Module 的函数里调用某个函数可能会导致无限递归。这个相对来说是比较容易修复的,只需要把 IM Module 调用那个函数的移动到事件队列里延迟调用就可以避免递归了。但这个问题并不会在其他任何 Qt 程序中出现,相信也只是在某个 LibreOffice 的版本无意之中导致的。说实话这种问题并没有一种办法归结为是谁的“过错”,毕竟我相信相关的 API 并没有相应的文档来定义这么细节的调用是不合法的或者可能导致问题。

2、Gtk 的 Client Side Input Panel 的语言 tag 失效

Fcitx 5 有一个功能,让 Pango 优先用指定语言的字体显示文字。例如骨字在日语和中文中的字形是不一样的。Fcitx 5 中可以让日语输入法用日语字形,中文则用中文字形。Gtk 的 Client Side Input Panel 和 Fcitx 5 的 Classic UI 使用了几乎相同的代码,但是出于某种未知的原因,不知道从什么时候开始这个功能在 Gtk 的 Client Side Input Panel 就失效了。我尝试了半天最后采取了一些 Workaround 来暂时回避。

3、zwp_input_method_v1 的支持问题

Wayland 的输入法协议之前也有很多地方吐槽过了,但让我出乎意料的是 KWin 采取了非常混搭的做法使用这个协议(并非不行,只是确实很意料之外)。首先介绍一下背景,Wayland 原生输入法协议是分为两个部分的,一部分是程序和 compositor,另一部分是输入法和 compositor 之间。程序和输入法之间的协议是 text-input 系列,而输入法和 compositor 之间则是 zwp_input_method 系列。

问题是 text-input-v1,v2 是和 zwp_input_method_v1 配套设计的,而 text-input-v3 和在野的 zwp_input_method_v2 是配套设计的。当然,考虑到 wayland-protocols 里面只有 zwp_input_method_v1,以及 kwin 的这个支持是给 Maliit 用的,也是可以理解的。但 text-input-v3 的 API 变化在某些方面和 zwp_input_method_v1 就有些格格不入,总之就是凑吧凑吧凑合能用。

但我从 5.23 开始关注这个,结果到最后我给 KWin 和相关的库写了接近30个PR。每当想起这段我就在想,我好好一个输入法开发者怎么就去写 Compositor 了。

这一部分按下不表,而 text-input-v2 有一个特别的事件,为了隐藏虚拟键盘,可以请求 compositor 来隐藏。但这个功能在桌面用键盘的输入法就会导致输入窗口永久被隐藏起来。我琢磨半天想出了一个 workaround,但这个 workaround 却又反过来会导致 weston 出问题。

后来幸好我又想出了另一个 workaround 才同时支持了 weston 和 kwin。zwp_input_method_v1 已经属于很故纸堆的协议了,也不会得到今后的更新。但很多行为其实都没有明确的定义,幸而实作只有两个,因此很多实现我就变成依靠他们实现的行为来决定。

4、Chrome 的 Wayland 输入法问题

Chrome 的 Wayland 输入法一直一个浆糊的状态。首先,Ozone 早期不支持 Gtk IM Module,只支持 text-input-v1 实现了一个输入法。现在问题是,text-input-v1 支持的 Compositor 只有 Weston,也就是说支持几乎等于 0。最广泛被支持的 text-input 是 v3,KWin wlroots GNOME 都支持。

然后他们就搞了一个支持 Gtk 4 的 IM Module,但问题来了,他们的所谓支持采用了一个非正常的使用 Gtk API 的方式,导致了 Gtk 自己的 text-input-v3 实现和 Fcitx 5 的 Client Side Input Panel 都无法正常使用。后来我倒是想通了,在最新版的 Fcitx5 Gtk 里可以略微做一个检查来临时禁用不能用 Client Side Input Panel 的情形。这种情况下好歹能显示一个位置错误的输入框。

而且根据 Chrome 的架构,他们是不可能用 Client Side Input Panel 的,因为他们内部就没有真实的 Gtk 窗口来绘制(对比 Firefox,Firefox 是用 Gtk 创建的窗口)。他们唯一正常支持输入法的希望应该就是把 text-input-v1 改成 text-input-v3(或者同时支持两个)。

5、Firefox 98alpha 的输入法问题

https://bugzilla.mozilla.org/show_bug.cgi?id=1751339

这个问题倒是 Archlinux CN 的群友优先发现的,幸好发现的早,早早的就通过 bisect 定位了导致的问题。虽然,我并不能理解这个改动牵扯了什么 Gtk 内部的问题导致窗口的销毁再重建,以至于 Gtk IM Module 接收到的是一个销毁了的窗口,但反正 Revert 回去了现在没问题了。

6、神秘的 Twitter 输入框输入法问题

说起这个问题,不得不说这个问题折磨很多人很久。而且不管是在 Chrome 还是 Firefox 上都有不同的表现:https://bugzilla.mozilla.org/show_bug.cgi?id=1735227 https://bugs.chromium.org/p/chromium/issues/detail?id=952181

最后追溯追溯追溯到底,竟然追溯到了这个输入框所用的 Javascript 上 draft-js 昨天我反正顺便加了一笔我的研究,但相关的在不同平台(含非 Linux)上至少我就能找到 4 相关汇报:

https://github.com/facebook/draft-js/issues/3109

https://github.com/facebook/draft-js/issues/2227

https://github.com/facebook/draft-js/issues/1320

https://github.com/facebook/draft-js/issues/1301

我一个输入法开发者,怎么就去看 React js 了。但光看这个 bug 的时间,我怀疑已经存在了非常长的时间。不管在什么平台上,输入法用户都是挺没有话语权的。

7、SDL2 和 Fcitx 5 的输入法小问题

这个说到底还是我自己弄出来的,我几年前给 SDL 加的 Fcitx 5 支持,在传递 DBus 参数的时候,传了一个错误的 int 类型,导致访问了无关的内存,导致了发送给 Fcitx 5 的 Capability Flag 可能意外包含 Client Side Input Panel 的 Bit 导致无法正常显示输入框……而很多分发 SDL 的是不会立刻获得更新的(甚至永远不能),例如 steam 的游戏。

所以结果就是我决定在 Fcitx 5 内部加一个 Workaround 来解决这个 bug(检查某些 bit 是否有不正常的数值,如果有,则抛弃)。总之,凑合能用。

8、SDL2 的最近的其他小问题

有一个人来汇报他没法在 Dota 用输入法,结果发现是他设置的某个快捷键无效。向下研究,则是 SDL 没有发送所有按键事件给输入法。然后我测试着测试着,就发现 SDL 的 ibus 实现也有 bug(因为 Fcitx 5 支持模拟 IBus,所以我顺手这么一测……),SDL 的 Wayland 输入法也有 bug,SDL 的 Wayland 按键处理也有 bug……

然后就又给 SDL 写了 4 个 PR ……

我一个写输入法的怎么又去看 SDL 代码了。

Posted in 日志 | 5 Comments

Fcitx 5 and multiple wayland compositor

Actually there is nothing so special about this feature, it’s just come freely with the multiple X server support. I just realized that WAYLAND_SOCKET passed from compositor can be just sent via DBus to the actual fcitx5 server, without the need to let compositor start Fcitx 5 directly. There will be a new small tool included in the next release (fcitx5-wayland-launcher). It can be used to initiate a new wayland connection from Fcitx, even if WAYLAND_SOCKET is required to be used link kwin or weston.

Some people may find it useful if they want to keep Fcitx as a user-level daemon. I didn’t test it, but I think this is what can be done:

  1. Remove all other method of auto start mechanism.
  2. create a user systemd unit, with command fcitx5 -k. The “-k” allows fcitx 5 to be kept running even if display server is gone.
  3. Make your X11 or wayland desktop to run a command to start a new X connection or Wayland connection.
Posted in fcitx development | Tagged , , | Leave a comment