梦幻的夏日圣地巡礼

很少会用梦幻这样形容一段时光。

今年夏天,踏上了久别了12年的土地。不过即使在过去的时间,我也没有去过这类活动的机会。

一个月的回国旅行中,我终究是给自己留了两天的时间完成一个梦。

12年前的自己为什么没有去过这种活动呢?当然,现在可以说,因为那时还没有崩坏3嘛。那时的自己还没有找到这种可以上升到可以被称作精神寄托一样的事情。说实话,地下城与勇士,曾经自己也是玩了可能约有10年的跨度,不过总是觉得和那个世界有一种疏离感。

但感觉崩坏3,当然还有其他后续的作品,感觉是不一样的。 可能这也有一定的因为自己离开中国太久了的原因。以前也喜欢过 Fate,东方,Macross,还有更多…不过总觉得自己也有在此之上的情感在。

上篇:上海

给自己安排的其实事情是很简单的,在上海的那天去中山地铁站圣地巡礼,顺便去一趟米哈游楼下看看,中午虽然没有流萤活动的预约,不过也是打算在外围转一转。下午去百盛ZX随便逛逛,晚上去崩铁流萤的大屏广告打卡。

那天早上从虹桥机场出发,早上还下着雨。还去全家当场买了一把伞来用。

早上大约9点,就到了中山公园地铁站。2017年登上崩坏3的舰桥以来,她们的故事就一直陪伴着我,再后来在未定,原神,星穹铁道,绝区零遇见了新的伙伴,但是崩坏3可以说是我在这些游戏中的白月光了。

在去中山公园的路上我就已经在两部手机上提前缓存好了 Reburn 和毕业旅行两部动画短片,把几个场景都重新刻在脑子里。

圣地巡礼到底意味着什么?谁都知道,那个世界的故事是虚幻的,但是,创作他们的人确实和自己生活在同一个世界上,他们取材的内容也来自自己生活的世界。基于这样一种想法,圣地巡礼短暂地,将现实和虚幻的界限模糊了。

可能并没有人理解为什么早上会有一个人在地铁站对着奇怪的东西自拍到底是在干什么。(当然,曾经也有打卡活动,不过那也是过去错过的事情了。)

然后就是顺道路过米哈游一下。路上还遇见了打伞的员工(?)小姐姐,感谢带路。

当然,并没有成功进入参观。他们其实安排了周末开放,但是可惜我是在周三过去的。

一路地铁上还看到了很多别的手游的广告,上海真的是中国二次元之都。

中午吃饭过后,之后就是转头去往鲁迅公园。

说实话,自己其实当初并没有想到自己能赶上《夏日萤火之约》的活动,当初就根本没有去抢票。尽管留下了这样的小遗憾,但是这样就好。感觉自己这一路都是在弥补曾经的错过,但是又在创造新的错过。

自然,没有门票的我只能在外面随便转转。不过拍到了星巴克的cosplay流萤的小情侣(也许并不是),路上遇见了花火(请原谅我赶路)。

话说选了甜爱路这个地址做活动……老米你别太爱。

下午去百联一方面是和朋友约了晚饭,另一方面就是想去看看店里有什么东西。

路上还看见了老凤祥的星铁联动广告。其实百联店内我是转了好半天,真的没有看到特别吸引我的东西。最后就是买了一个尼尔机械纪元的设定集。倒是看见了诡秘之主的小活动有点小惊喜。本来看到高达模型,想着是不是买一个回家拼一拼,然而并没有看到自己熟悉的作品(是的,只有高达00)。只能感叹可能自己只是活在过去罢了。

晚饭后,其实就是想要去拍一下那个流萤的大楼广告。

下篇:厦门

这次行动其实并不是在我原本计划的路线上,但是非常惊喜的发现,流萤的线下活动还有一个厦门站。因此一不做二不休,我直接就从龙岩火车直接进行一个一日行。

其实原本来说,我并不期待会有什么特别的活动,但是最后的收获却是意想之上。

因为本身这个活动的主会场是在上海的,几个非上海的地点实际上只有一点点打卡的布置。早上我到了之后,其实几乎没有人。不过稍微等一等之后,也不断有别的玩家来打卡。

还等到了可爱的 coser 小姐姐。说实话那天厦门是真的热,我看着她穿 cos 服都替她感觉热……

旁边甚至还有一个咖啡厅,因为在海边所以说是中国最美的咖啡厅之一,旁边还立了个国家地理宣传用的牌子。和一个同好聊天起来还一起吃了个饭,没想到他也是从上海过来的,聊天聊了很久,他后来还送了我一个开拓的列车票徽章。

考虑到开拓在游戏中的意义,这是不是也算得上一种开拓呢?

结:然后重新出发

我一直想要把这次的经历写下来,但是因为种种原因,拖到了2024年快要结束的今天,才找到了足够的时间和心情来完成。这反而让那两天的经历显得更加难能可贵。

短短的两天当中,难得地我找回了对自己生活的主导的权力。

随着年龄的增长,也越来越能够体会到,能拥有一段只属于自己的回忆是多么难得的事情。

这么多年这个博客的内容也早已横跨了 15 年的时光了。从一个月能有两位数的文章,到今天甚至会出现一整年完全空缺。是我的表达欲望减少了吗?我觉得并不是。

我给我自己找的借口是,有空再说吧。可能第二条大概是,反正也没人看。

大多数时候,其实很难认为自己能够成为自己生活的主人。工作,孩子,家人,世界上总有那么多的事情等着你去做。所以有的时候,那个世界的她们才会变成像是精神寄托一样的事情。她们不是真实的,却又在无时无刻地鼓舞着我。她们可以遭遇那样的困难,她们的感情是那样炽烈,她们又是那样坚强,在面对无数挫折之后也能抬起头来重新面对生活。

她们的故事还在继续,我也是。愿两个世界的我们的将来都能一帆风顺。

Posted in 日志 | Tagged , | 2 Comments

去除 Fcitx 5 码表的 PUA 字符

首先来讲一些历史,在更加久远的 Fcitx 3 的时代,Fcitx 的码表文件是使用 gb18030 存储的。在 Fcitx 3 -> Fcitx 4 的过程中,所有的文件都被替换为了 UTF-8,但是受限于当时的 glibc,出现了很多转换的结果是 PUA 区的情况(Private Use Area)。从根本上来说,导致这个的原因是 Unicode 标准仍未收入这些文字,因此采用 PUA 存储这些文字的权宜之计。

Unicode 有一些历史文档记载这些,但是并不是所有我们遇见的字符都记载其中 https://www.unicode.org/L2/L2004/04161-hkscs-gb-pua.pdf

但是时过境迁,现在已经过去十几年了,因此这些 PUA 的字符也都获得了对应的码位。也就是说,是时候把他们重新拉出来更新了。

对于 fcitx5-chinese-addons 当中的码表(实际上是 libime 这个包),这倒不是一件难事。只需要把 fcitx3 的文件找回来,然后在新的 glibc 的系统上重新转换一次即可。为了验证当年的流程,我还特地安装了一个 debian 5 的系统重现当年的转换。

而这也确实证实了,当年确实是这样得到那些 PUA 的字符的。

而对于 fcitx5-table-extra 来说,这就有些难办了,他们当中的文件我们并没有原始的文件。这该怎么办呢?kingysu 发现 AR PL UMing HK 和 AR PL UMing CN 能够正确显示其中的大部分字符,而这正式取决于他们原始的文件的码是 BIG5-HKSCS,还是GB18030。

我们一开始的想法是全手动处理,一个个根据字形去查找对应的文字,据此我们也用了 https://www.qhanzi.com/index.zh-CN.html 一些手写中文识别的文字。还有用汉典 zdic 利用偏旁,仓颉,进行查询。

对于一些我们用以上方法都没找到的字符,我本来是想试试看用 fontforge 打开看看能不能直接搜索字形,然而我发现 fontforge 实际上对于 AR PL UMing 的字体可以显示他们实际引用的 unicode 的码。

而 Rocka 提示我们,可以直接用 python-fonttools 的 ttx 直接导出字体的信息。实际上这里导出 glyf 表之后,可以获得形如

的文件。uniXXXX.H 是 Big5 的 PUA,uniXXXX.C 是 GB18030 对应的 PUA。剩下的工作就是直接写一些只用一次的垃圾小脚本把这些信息提取出来即可。因为写 Python 脚本的突出一个糙就不展示了。

然后我们就得到了一个这样的映射,在 Uming 字体看看起来完全一致,但是实际上是不一样的 Unicode 哦。

如果用 Fcitx 的 Unicode 功能(复制然后Ctrl Shift Alt U)就可以容易地看出区别。

剩下就是把他们完全替换成正规的 Unicode 字符即可。

https://github.com/fcitx/fcitx5-table-extra/commit/0b3e04256b5b49c72a04e88da80bf34e5bba4b3f

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

我和 Fcitx 的 14 年

人的一生能有多少个 14 年?

开端(2009)

commit 95f13144a52d409da387af4f1a25aa01bc6bb653
Author: Weng Xuetian <wengxt@gmail.com>
Date:   Sat Jan 16 06:17:12 2010 +0000

   Add Kimpanel Support

这可能是一切的开始。其实最早给 Fcitx 的贡献,就是 3.6.3rc 之后给 Fcitx 增加 Kimpanel 的支持。2008 年 KDE 4 刚刚发布,之后因为一些偶然的契机,发现有人为了 KDE 界面的集成,为 KDE 和 Fcitx(也包括scim 和 ibus)增加了一个基于 DBus 的面板协议。当时 Fcitx 的相关的代码因为 Fcitx 并没有一个插件架构,因此是保存在其中的一个分支当中的。

当年的这个时刻我竟然也写了博客记录,当我找到它的时候,它夹在两篇略羞耻恋爱感想的中间……

当我发现记录一切缘起这篇博客是在 102 页的时候我也是吃惊不小的。

Fcitx-dbus-svn ON AUR
Posted on October 25, 2009 by csslayer
由于我现在一直使用KDE桌面,某日曾经发现了个好东西:kimpanel
这个Plasmoid帮助Plasma和linux当中的输入法实现了一个统一的界面,目前linux下面流行的三个输入法fcitx, scim, ibus都由作者实现了一个后端。由于某些原因,Fcitx界面和程序是不分离的,因此只能用修改源码的方式使其支持kimpanel。kimpanel通过dbus和输入发进行交互活动,从而完成界面的统一。
fcitx-dbus的原作者貌似很久都没有维护了,因为最近fcitx修改了大量的bug,因此原有的fcitx-dbus还保留着这些bug……由于Archlinux的AUR上的fcitx-dbus-svn的包是我打的,因此我把我的port给放到AUR上了……原作者和各位用户不要伤心啊……?
貌似kimpanel还有一些问题,和fcitx的支持不是那么好,因此我(就算是为了我自己)也修改了一部分的bug……
跑去fcitx的issue发了个贴,暂时没人理我……又和fcitx-dbus的作者发了个信……也没理我……囧

总而言之,我就莫名地接手了这个项目的 fcitx 的部分,然后谁也不知道这埋下了一颗怎样的种子……关于我这一年的当时的生活……和我现在的老婆谈恋爱一年多了。大四刚刚开始的样子。

不断的维护和第一次大版本的飞跃(2010)

总的来说,这部分时间的提交历史我意外发现了一个历史悠久的噩梦,就是托盘图标。这部分如果展开讲的话,会涉及太多太多技术的细节,不过这时我回顾起来我才发现,我大概是真的不懂完全在盲人摸象一般修复那个托盘的透明问题。这个问题可能乃至到了 Fcitx 5 的时代仿佛鬼魅一般归来过……

但总之这也是给 Fcitx 开发代码的一个侧面,由于依赖的精简和 Toolkit 的缺位,很多基础的功能都是从更加底层缺少文档的协议实现起的。想象一下,在 Qt 中只需要 new 一下就可以创建的托盘图标,在 Fcitx 5 中却有 1.5k 的代码,实现了两种完全不同的方式…Toolkit 实在是替你负重前行了太多。

第一个大版本究竟是为了什么呢?现在的我可以说也是记忆模糊了。但那时我维护了一个内码是从 gbk 转到 utf8 的分支。在 3.6.4 的发布之后它也合并到了主干上。一方面,从这里的提交文件可以看出,这里为了当初 Fcitx 停止开发的其中两个原因「中文配置文件」和「用GB存储数据」以我个人的想法进行了修改……这里用描述型文件来生成界面的想法已经初具雏形……不过即使到了 Fcitx 5 的时代,Fcitx 3 的中文码表格式也依然可以兼容使用……但因为 dbus 强行要求 utf8 编码字符串,因此将整个内核转换成 utf8 其实也是一种势在必行的修改。

另一方面 fcitx-utf8 分支的重要功能之一……皮肤支持也不得不引入了更多的依赖,为了加载 png 文件而使用了 cairo。这里我还记得因为使用 cairo 而相关的字体问题。cairo 的文字绘制是没有 fallback 功能的,所以我又不得不引入了更高级的文字排版库 pango。

时隔一年之后,终于 Fcitx 到达了 4.0-rc1,回顾当年的发布公告,很多现在保留的功能也都是在整个版本发布的,例如搜狗词库转换。

另外里面的一个功能就是输入法可以由插件加载了,虽然只有 sunpinyin,但是也是可扩展性方面迈出的一大步。

https://groups.google.com/g/fcitx-announce/c/BBueYZSRXiY

* 皮肤支持,采用cairo做绘制,pango负责字体,界面支持真透明;
* 拼音支持多个词库:利用createPYMB创建的词库放在~/.config/fcitx/pinyin下面即可;
* 额外的输入法支持(目前只有fcitx-sunpinyin);
* 基于gtk的图形配置工具fcitx-config(并不包含在fcitx源码包中);
* 右键的菜单支持。

配置界面采用 gtk 其实在当初也是仔细思考过的……就像前几个月的 libime 用个 boost 都有人 BB 半天的事情。

在这个时期,每一个额外依赖的引入我都是和自己内心做了巨大的斗争的。

第一次大重构(2011)

4.0 没有几个小版本号,我就开始思考 4.1 要进行大规模的重构的事情了……一方面,同时存在的两套界面,多个输入法也让那时的代码开始有点承受不住发展的方向了。从 4.0 到 4.1 有好几个大变化,一个是沿用至今的插件架构,另一个就是构建系统从 autotools 转到了 cmake。

autotools 的并行编译手写实在是很容易出问题……和语法更加清晰的 cmake 相比差的很远。我还记得那一段时间我花了很长的时间构思这个虽然现在看起来还十分不成熟的架构,我从学校的角落的门走出去去买肯德基的时候还在边走边思考。

最终我拿出来的方案就是一切功能皆插件,以及一个插件间互相调用避免链接的依赖关系网。

Why fcitx need refactor?

这里 GNOME 已经给了 fcitx 第一个闷棍,就是输入法界面不能显示于 gnome shell 界面上方。当然当初我也并没有觉得什么。不过也为了后来的一些事情埋下了种子……

为了解决 GTK 的问题我也实现了 im module。我还记得和 sunpinyin 的一个开发者在 bugzilla.gnome.org 上为他们的 xim 支持问题争论的事情(sunpinyin 有一个纯 xim 实现 xsunpinyin)。im module 其实在当初也是被逼上梁山的产物,因为还有 xim 在 firefox 中的坐标 bug 也是有十余年历史才修复了一半?

毕业,和 GNOME 的仇怨,和迷茫(2011-2012)

在这一年发生了很多事情,一方面,生活上毕业,申请学校,和被迫干不想干的事情的迷茫困扰着我。我其实早在这一年大概就意识到,我不是一个喜欢学术研究的人。我喜欢的是工程方面的工作,从小当我第一次玩到 LEGO 的时候,我就觉醒了这种构建积木的快乐。

但是女朋友毕竟已经出国了,虽然想来我多少骨子里是一个很被动的人,在很多事情上都被生活推着走。那会儿也没有想明白,出国了之后能干什么。

另一件事就是 GNOME 3.6 集成 ibus 给我巨大的打击。基本上,从我刚接触开源软件开始,就有那么一些幻想的滤镜,大家是友好的,是想要一起做成什么事情的幻觉。

https://www.csslayer.info/wordpress/kde/fcitx-kde/

https://www.csslayer.info/wordpress/fcitx-dev/why-gtk-apps-are-likely-to-suck-on-input-method/

我得承认我是迷茫了很久,从 https://www.csslayer.info/wordpress/fcitx-dev/why-fcitx/ 一直到 https://www.csslayer.info/wordpress/fcitx-dev/re-ask-why-fcitx/

我还能记得在夜晚学校的公交车上因为 GNOME 而气到胸闷的时候(这件事是在我留学的学校),所以真的,我头一次对我投入这么多感情给 Fcitx 而感到后悔。

但总而言之,后来的故事就是我硬生生是被 GNOME 逼出了逆反心理。

「凡高大者,我无不蔑视。」

生活的问题,孩子的出生,和逃避现实(2012-2016)

前面我也说过了,我在生活的很多问题上其实都没有认真的思考过,而且我还是那种不知道放手的人。就像我不肯放手 Fcitx 那样。其实回过头来看,很多事情也许放手会变的很不一样,例如我应该早点 Quit PhD。

2013 年我结婚了,但是学校方面的生活也没有因此而步上正轨,研究生最后一年的自我堕落终于还是找上了我。在留学之前我想的其实很好,尽管申请学校方面是靠了很多的贵人的相助,但是那会儿我幻想着还是能够抛弃因为提不起劲头而感到一事无成的自己从头开始。

然而事情显然并没有这么好。

当你给你自己找到一个借口的时候,例如孩子的出生,就更难以继续那些原本就不想做的事情。然而不想要放手的优柔寡断又开始不停的作祟,导致陷入了「我还想试一下」,「但是我的身体只想要摆烂」这样奇怪的死循环中。

如果继续说下去似乎和 Fcitx 就没多大关系了,这段时间 Yichao Yu 写了很多的功能,有许多我其实至今都没有仔细看和了解过,例如著名自检脚本 fcitx diagnose 就基本上完全来自他的手笔,里面 shell script 的花活至今我几乎从没认真研究过。

然后,就是你写得越多,迷茫就越多。当你积累的经验增长到一定程度的时候,就会回头发现从 Fcitx 3 时代起缝缝补补的马车已经很难承担更多的任务了。而且还是自己在那个青涩时代写出来的代码,充斥着大量脑袋一热的设计和经验不足而留下的难以扩展的问题。

想要推倒重来的念头在 2013 年就产生了,而其结果也就是夭折的 https://github.com/fcitx/fcitx-ng/ 。当你坚持想用 C 写些什么的时候,语言本身的负担就越来越沉重,终于到自己也再也推不动的时候,也是借着 C++1x 的东风,想要试一试全新的 C++ 的体验。然后终于有了 Fcitx 5 开端。

Fcitx 5 – 缓慢而全新的开始(2017-2020)

直到 2016 年年中,它才开始短暂的恢复活力。毕竟自己的第一孩子已经半岁,偷闲摸鱼的时间也算增长了不少。因为 fcitx 5 而诞生的项目有三个,xcb-imdkit,fcitx5,libime。xcb-imdkit 完成的最早,然后 fcitx5 和 libime 同时推进。Fcitx 5 因为 kdbus 的东风而决定尝试用 sd-bus 作为 dbus 实现 sd event 作为 event loop,不过后来又加回了 libevent(最新的 master 换为了 libuv) + libdbus。

拼音的首个里程碑大概是 2017 年 4 月,然后 2017 年 10 月左右大概有了最初的新码表。之后大概就是不断的 dog fooding,以及不断吸引到有人来测试。我和我自己定下的约定就是不能比 Fcitx 4 缺少什么功能,因此最后的时光大概就是移植,移植再移植。

快车道和新的伙伴们(2020-2023)

在 Fcitx 5 发布一年之后我也写过一个记录 https://www.csslayer.info/wordpress/fcitx-dev/one-year-in-fcitx-5/ 那里就已经提到了 android 移植。虽然可能也是某人头脑一热的决定,不过到现在也变得更加完善,参与的人也变多了不少。

然后就是 open kylin 的虚拟键盘作为去年最重要的功能更新之一。现在还有人正在进行 mac 的移植工作。对我自己来说我最大的成就大概是 libime 新模型的训练吧……这个是货真价实因为数据量级的问题,而不得不使用钞能力来解决的。

所幸这个最后的结果是我很满意的,现在我就在用着 Fcitx 来输入这篇博客。我对于它预测准确度可以说是相当满意的。

未来是?

还有很多工作需要完成,不过感觉也已经渡过了最难的时候。在去年年初的时候我家庭成员的数量又翻了一倍,但我也没有以前那么焦虑了。虽然我自己的未来还有很多不确定,但 Fcitx 的未来至少在许多朋友的帮助下又打开了更多的可能性的门。

时钟已经指向 1:30,虽然我感觉有许多话想要讲出来,但是也总是在这种时候才能感受到自己语言方面才能的匮乏。

若要问我有什么想法…大概感觉就是他已经是我生活的一部分。

至于关于技术上的体会,有机会再聊吧。

不快乐的,终将过去,快乐的,总会留下。在不远的未来再见吧。

Posted in 日志 | Tagged , | 15 Comments

Accent color support in Fcitx 5

Recently a new feature was added to XDG desktop portal, which allows portal to return an accent color.

Since the default theme of fcitx5 is almost monochrome, it is a good addition the default theme together with the dark/light theme support.

Here’s a demo of this feature on master.

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

Key repetition and key event handling issue with Wayland input method protocols

I do have lots of complaints about wayland current input method protocols. Some of them are just lacking features, but this issue is the one that I think have design flaw from the beginning.

Let’s first review how the keyboard event is handled with input method on Wayland and X11.

The XFilterEvent would use XClientMessage to transport the key event to input method, which would actually introduce another message to X Server which is omitted in the graph above. Other than the XClientMessage, other methods may also be used, including raw socket, or DBus which is used by fcitx/ibus.

In Wayland, the things become different.

The input method first places a keyboard grab, to make compositor send all key event to input method server first. Then, depending on the result of key event (filter or not), the input method server may forward the key event back to compositor, then the key event will be forwarded from compositor to application, if input method server find this key is not relevant to the input method engine’s logic.

It may look ok right now, but if you put key repetition into consideration, you’ll find more issues with this design.

Imagine a following scenario:

1. User is using an editor to type some text, and already have some text in application already.
Let’s just say there’s some existing Chinese text: 你好.

Literally this means “hello” in Chinese 🙂

2. User types some new text and the text is stored in input method’s buffer to be converted to another language.

Hello, world!

3. User thinks that all the text is unwanted so the user press backspace and hold it, expect key repetition to remove the whole line, including “shi jie” and 你好 which is already committed.

Here is where it becomes problematic when Wayland decides to use keyboard grab for input method, and client side key repetition.

In X11, key repetition is done on the X Server side, client doesn’t need to worry about the key repetition generation. Client will just receive multiple key press events (release is optional, depending on a “detectable key repetition” option) until the key is physically released.

In Wayland, the key repetition is done on the application(client) side, the common logic is to implement this feature is that, when client gets a wl_keyboard.key press, it will start a timer and generate new key event on its own.

When you put input method in to this example, you will notice that, the very first “Backspace” is forwarded to input method and is invisible to client. So client will not be able to initiate the key repetition logic. That means, if the key need to be filtered by the input method, the input method server have to do the key repetition on its own.

In the case above, since there are texts in the buffer (shi jie), the first backspace will delete “e” in the buffer, then “i”, and then “j” etc..

When the last character in the buffer “s” is deleted, the buffer will become empty, which means, the next “repeated” backspace event need to be forwarded to application. This can still be done via zwp_virtual_keyboard_v1 or zwp_input_method_v1 depending on which version of protocol you are using.

Expected backspace behavior

But the problem is that, what do to next?

Let’s suppose the key repetition option is that “initial delay is 600ms, the repeat rate is 25/s”. The re-injected backspace can only trigger client’s own key repetition after 600ms, while user would expect it is already in the repeat phase, which will generate a backspace every 40ms. So input method have to continue to generate key press since application does not know the key repetition is already started in the past. But, after the first fake key repetition from input method is re-injected to the application, the client side key repetition logic will be now triggered. If input method doesn’t do anything to prevent it, the client will start to trigger key repetition after 600ms. If that happens, we will see both input method and client generating key repetition at the same time. To prevent this from happening, fcitx5 does a workaround by always sending a fake key release immediately after it send a key repetition from the input method side in order to stop the just started client side key repetition timer.

This seems to be very hacky and unreliable to me, since we are trying to “take over” the key repetition on client side, instead of hand it over.

Lets consider another scenario where it is totally broken.

Imagine a input method that can dynamically convert the text around cursor into preedit, and shows alternative text for the word around cursor. This is very common on mobile phone: you can click on a word and the word will be “underlined”, and alternative candidates is shown on the on-screen keyboard.

1. Image user have text “Hello, world |” (| represent the cursor location in application.

2. user starts to press backspace.

3. the first backspace press is ignored by input method, since there’s no word around cursor.

4. client side key repetition kicks in. Please notice that client side key repetition will not be forwarded to input method under current version of protocol

5. Text becomes “Hello, world”, and input method will try to consume “world” and convert it into preedit text and put “world” in the buffer on the input method server. Which means, from this point, any new backspace event should be handled by input method.

Consume the word “world” is and convert it to preedit is not a feature currently supported under fcitx, but we do want to implement such things in the future. Actually, fcitx5-unikey is already able to do something in a similar way, see the video below.

fcitx5-unikey’s consume existing text and re-edit feature. It’s not triggered by “backspace” but “e” in this case, but you get my idea.

But if you remember how client side key repetition works, you will notice that it will never be forwarded to input method, thus the backspace is “leaked” from input method into application, and will cause unexpected behavior.

My proposed solution to solve this is that: just go back to the old X11 model of forwarding event to input method. The procedure would look like:

  1. wl_keyboard.key send to application
  2. text_input.key send key to input method through compositor, this includes all key events, including the repeated key events generated on the client side.
  3. input method server forward it back with the old interface
  4. application got the input method forwarded back event via a new event text_input.forward_key, instead of from wl_keyboard.key.

This introduce more round trips between compositor and application, but it solves the whole issue in a much more cleaner way comparing to the other solution I can think of. And this new interface can even help on other issue like type-to-search’s chicken-and-egg issue, also this may make browser happier by allow them to stick to the javascript key/IME event standard better.

If one want to stick to keyboard grab model, they may have to add a lot of tricky new events like “handover ongoing key repetition” etc, which from my point of view would introduce much more complexity and easier to go wrong.

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