2715 字
14 分钟
2026年的fcitx折腾记

最近用 Codex 搞 vibe coding 有点上头,也因此重新把主力系统切回了 Manjaro KDE。Windows 当然不是不能开发,但 Codex 对 PowerShell、路径规则和 Windows 那套工具链总差点意思,搞起项目来时不时就会磕绊一下。相比之下,原生 POSIX 环境更贴近它熟悉的工作方式,很多事情交给它处理都顺手得多。

Linux 的另一个优势是几乎一切都可以配置,自定义空间也足够大。Codex 不仅能替我查配置、改配置,面对更具体的需求时,还可以顺着日志和源码一路追下去。许多 Linux 软件本来就是开源的,现有选项满足不了需求,就直接改源码、编译、安装;这类深入系统组件的定制,在 Windows 上很难有同样的施展空间。

我几年前也很爱玩 Linux,只是后来实在折腾不动了。那时候解决一个问题,经常要排查大半天,搜索引擎开一堆页面,再对着互相矛盾的帖子改半天配置,最后还是回到 Windows 养老。没想到有了 AI 以后,这个最劝退我的问题突然不再那么可怕了。

这次 Fcitx5 折腾就是一个很具体的例子。我负责提出需求、截图和实机验收,Codex 负责检查系统、修改配置和源码,最后不仅编译了 Fcitx5 的 Git 版本,还给 Classic UI 加了 Wayland 和 X11 两套图片窗口。环境是 KDE Plasma 6、Wayland、200% 缩放,下面主要记录中间那些“看起来已经对了,实际一用还是不对”的坑。

消失的配置界面#

最开始是我发现运行 fcitx5-configtool 没有出现配置窗口。Codex 检查安装状态后发现,系统里的这个命令只是一个入口,真正提供 Qt 配置界面和 KDE KCM 的包并没有正确安装。

Codex 补上 fcitx5-configtool 后,fcitx5-config-qt 和系统设置中的 Fcitx5 配置页都恢复了:

终端
sudo pacman -S fcitx5-configtool

这一步不复杂,但也提醒了我:命令存在不代表图形界面本体就一定存在。以后再遇到配置工具“运行了,但什么都没发生”,先查它究竟是可执行文件还是一个包装脚本。

Caps Lock 只能做一件事#

我提出的目标是让 Caps Lock 专门切换中英文,不再承担大写锁定。Codex 最初尝试直接在 Fcitx5 中绑定 Caps Lock;我实测后发现输入法确实切换了,但大写锁定也同时触发了。这种状态看配置完全正确,实际敲字却立刻露馅。

收到反馈后,Codex 把方案移到了输入栈更靠前的位置:让 keyd 把物理 Caps Lock 改写为 F13,再让 Fcitx5 监听 F13。

/etc/keyd/default.conf

/etc/keyd/default.conf
[ids]
*
[main]
capslock = f13

改完后重启 keyd

终端
sudo systemctl restart keyd

然而事情还没结束。我再次实测,发现 Caps Lock 竟然变成了“打开系统设置”。Codex 继续沿按键链路排查,发现 KDE 使用的默认 XKB inet 规则会把 F13 解释成一个 XF86 功能键,因此还需要在 KDE 的键盘配置中加入:

~/.config/kxkbrc
[Layout]
LayoutList=us
VariantList=
DisplayNames=
Use=true
Options=fkeys:basic_13-24
ResetOldOptions=true

最后在 ~/.config/fcitx5/config 中把 F13 加入切换键:

~/.config/fcitx5/config
[Hotkey/TriggerKeys]
3=F13

完整链路就变成了:

物理 Caps Lock -> keyd F13 -> XKB fkeys:basic_13-24 -> Fcitx5 F13

这次必须打开一个英文输入框实际测试:连续按 Caps Lock 可以切换输入法,但不能再打出大写字母。只看配置文件或按键事件是不够的。

每个窗口保存自己的中英文状态#

接下来我又提出了输入状态方面的需求:终端保持英文、聊天窗口保持中文,窗口之间互不干扰;每次聚焦输入框时,还要提示当前处于中文还是英文。Codex 将它落实为下面几项配置:

~/.config/fcitx5/config
[Behavior]
resetStateWhenFocusIn=No
ShareInputState=No
showInputMethodInformationWhenFocusIn=True
CompactInputMethodInformation=True
ShowFirstInputMethodInformation=True

其中 ShareInputState=No 让不同窗口保存各自的输入法状态,resetStateWhenFocusIn=No 避免重新聚焦时被统一重置。改完可以执行:

终端
fcitx5-remote -r

之后在两个窗口中分别选择中文和英文,来回切换焦点即可验证。

200% 缩放下的模糊候选框#

行为问题解决后,我开始嫌候选框不好看,于是让 Codex 给 Classic UI 做一套新主题。Codex 先做出了深色版本,但我从实机截图里发现,字体、圆角边框和左右翻页箭头都有明显锯齿。

最奇怪的是,我对比出了一个稳定规律:同一个候选框在系统设置、Konsole 这类原生 Wayland/Qt 程序里模糊,在微信这样的 XWayland 程序里反而清晰。我还找了 Ori-fcitx5 的截图作为清晰度参考。

根据我的多轮截图反馈,Codex 中间试过几种很直觉的方案:

  1. 调小候选词字体;
  2. 取消整体缩放,只把字体放大;
  3. 调整 SVG 边框和圆角;
  4. 在 Classic UI 和 Kimpanel 之间切换。

它们能改变尺寸,却解决不了渲染路径已经被低分辨率栅格化的问题。尤其是边框和箭头一起模糊时,继续调字体基本没有意义。

继续查上游后,Codex 发现 Fcitx5 恰好在 5.1.21 之后刚合入一批 Classic UI 高分辨率改进,包括原生 SVG 渲染、Cairo 图案和避免亚像素坐标的整数取整。于是它基于提交 1426cce6 构建并安装了 fcitx5-git。我再次截图验收,Wayland 下的文字、圆角边框和箭头终于同时清晰了。

NOTE

这里真正修好的不是“字体”,而是 Classic UI 在高 DPI 下的整条绘制路径。未来正式版如果已经包含这些提交,就没有必要继续依赖这个特定 Git 基线。

自定义主题与候选栏右侧图片#

清晰度解决后,主题本身反而简单了。Codex 根据前面的反馈收紧了候选栏高度,保留深色背景和青绿色当前候选,做成了 Yuzi Slate

然后事情逐渐偏离了“换个皮肤”的范畴:我提出要在候选栏右上方放一张角色图,并且强调图片不能把候选栏撑高。

我先要求把素材的白边改成透明并裁掉空白。Codex 写的预处理只删除与图片边缘连通的白色背景,再裁掉外围透明区域;不能粗暴地删除所有白色像素,否则角色衣服、眼睛等区域也会被一起挖空。

如果把一张 160 像素高的图片直接画进只有约 50 像素高的候选栏背景里,会出现两个问题:

  1. 为了容纳图片,候选栏会被撑得很高;
  2. 不增加高度时,超出的图片会被窗口边界裁掉。

我连续反馈了“候选栏被撑高”“位置被图片带着下移”等问题后,Codex 最终让主题只在右侧预留约 170 像素的横向空间,不预留纵向空间。图片则交给独立窗口绘制,并以候选栏右下角为锚点向上延伸。

Wayland 和 X11 是两套实现#

在 Wayland 下,Codex 给候选窗口增加了一个独立的 wl_subsurface。它位于候选栏之上、输入区域为空,不参与候选栏本身的尺寸计算,因此图片再高也不会把候选栏向下推。

这套实现放到微信和 Minecraft 后又出问题了。我分别截图反馈:图片只剩候选栏高度的一小截。Codex 定位到这些程序走的是 X11/XWayland,而 X11 子窗口超出父窗口的部分天然会被裁剪。

于是 Codex 又写了一套 XCB 路径:创建透明、置顶、override-redirect 的独立窗口,根据候选栏的全局坐标放到右上方。候选栏隐藏、移动或翻页时,图片窗口也跟着隐藏、移动和重绘。

于是同一个主题实际上有两种后端:

Wayland: 候选 surface + 独立 wl_subsurface
X11/XWayland: 候选窗口 + 独立透明 XCB 顶层窗口

这也是为什么只在系统设置里测试成功还不够。最终至少要覆盖原生 Wayland 的系统设置和 Konsole,以及 XWayland 下的微信和 Minecraft。

每 15 分钟随机换一张#

“从文件夹中随机选一张图”是我一开始就提出的想法。Codex 先做了一个登录脚本,从图片目录随机挑一张生成主题素材;我后来发现它只能做到“每次登录随机”,桌面会话中并不会继续变化,于是进一步要求每 15 分钟切换一次。

既然已经改到 Fcitx5 源码里了,Codex 最终把随机选择也整合进 Classic UI:

  • 从指定目录读取 PNG、JPEG、WebP 和 BMP;
  • 保持原图纵横比,不强制拉成正方形;
  • 启动时随机选择一次;
  • 使用 Fcitx 事件循环中的单调时钟,每 15 分钟切换;
  • 多张图片时排除当前图片,避免连续两次相同;
  • 切换后同时通知 Wayland 和 XCB 后端重绘。

后记#

这次最深的感受是,Linux 桌面上的“输入法候选框”并不是一个孤立的小窗口。一个 Caps Lock 会经过键盘固件、keyd、XKB、KWin 和 Fcitx;一个看似普通的图片又会碰到 DPI、Cairo、Wayland surface、X11 窗口裁剪和桌面会话生命周期。

这套修改横跨按键映射、桌面环境和两套窗口协议。若还沿用过去一个人慢慢试错的方式,我大概在发现“调字体并不能解决模糊”时就耗尽耐心了,更不用说继续追到 Wayland 和 XCB 的源码里。现在我的工作变成了说明自己到底想要什么,在真实桌面里继续打字、截图和反馈;Codex 则负责沿着证据查配置、读日志和调整实现。AI 没有让问题凭空消失,但它把解决问题的成本降到了我愿意继续折腾的程度。

而 Linux 的开源与可配置,正好给了 Codex 足够大的操作空间。从按键映射一路改到 Fcitx5 的窗口实现,选项不够就补源码,官方版本不够新就自己编译。这种对系统组件一路追到底的自由,在 Windows 上几乎不可想象。

没想到几年以后,让我重新拾起这种折腾兴致的会是 AI。它改变的不只是我写代码的方式,也让我又有余力按照自己的想法改造每天使用的系统。原来 AI 还能这样改变生活,确实挺令人感叹的。

2026年的fcitx折腾记
https://yuzi.dev/posts/tinkering/fcitx5-tinkering-in-2026
作者
Yuzi
发布于
2026-08-01
许可协议
CC BY-NC-SA 4.0