Chrome/Chromium 今日 Wayland 输入法支持现状

似乎有不少人总是有疑问,Chrome的Wayland输入法支持到底是什么情况,能不能输入,支不支持,那么就姑且来总结一番。本文仅代表写作时的状态,不代表后续的情况。(以下用 Chrome 指代 Chrome/Chromium)。

首先简单介绍一下 Chrome 对 Wayland 支持的情况。对于 Chrome 这种跨平台的项目来说,肯定有自己的抽象层,从而能够高效地利用对应平台的 GPU,图形栈。现阶段来说,这一层抽象的项目的名称是 Ozone,更多详细的介绍可以参考 https://chromium.googlesource.com/chromium/src.git/+/HEAD/docs/ozone_overview.md。这里的描述是这样的:Ozone 是在使用了底层输入和图形的 Aura 窗口系统下的平台抽象层。一旦完成,这个抽象将支持各种系统,包括嵌入式 SoC,或者新的 Linux X11 替代:Wayland/Mir 来启动 Aura。

现在如果要在 Wayland 上用原生 Wayland 而不是 XWayland 来显示,那么将要使用 Ozone 作为它的图形栈。那么 Ozone 有什么样的输入法支持呢?在很长的一段时间内,它的输入法支持只有 text_input_v1,并且需要使用 –enable-wayland-ime 来启用。对于不了解 Wayland 输入法架构的人来说,这里对 Wayland 输入法的现状做一个解释。

Wayland 上的输入法分为两个部分,程序和 Wayland Compositor 之间的协议,和 Wayland Compositor 和输入法服务之间的协议。无论对哪个协议,都需要通信的双方同时支持相同的协议才能正常运作。Compositor 和程序间的协议名称是 text-input,目前的版本有 v1 – v4。Compositor 方面 v1 几乎没有支持,只有 weston 作为一个 demo 有简单的实现。v2 的功能是 v1 的扩展,但没有获得广泛的支持,也没有合并到上游的 wayland-protocols 里面。v3 则是 v1 的精简版。因为它已经合并到了 wayland-protocols 里,因此有较为广泛的 Compositor 和程序支持。text-input-v3 Compositor 的支持包括 mutter,kwin,wlroots,基本上可以说涵盖了所有 linux 主流 Compositor。text-input-v2 的 Compositor 支持则只有 KWin。而在 Toolkit 方面,Gtk 和其他一些基于 Rust 或者完全手写的 Wayland 程序支持的是 text-input-v3。 不知出于什么理由,Qt 只支持 v2 和 v4,相信主要有两个原因,v3 的功能不足,以及单纯的诞生时间的问题。

Toolkit / Compositorwestonmutter(GNOME Shell)kwinwlroots(sway等)
Gtkv3v3v3
Qtv2
Chromev1
其他如 winit 等v3v3v3
text-input 的支持情况

和输入法之间的协议则主要有 zwp_input_method_v1 和 v2,v2 并未合并到上游,只被 wlroots 部分支持,以至于至今稳定版的 sway 也不能支持显示输入框。v1 则有 weston 和 kwin 支持。KWin 支持 zwp_input_method_v1 主要是为了 Plasma mobile 和 Maliit,在 PLasma 5.24 我修复了绝大部分 kwin 的 zwp_input_method_v1 在桌面上的使用问题,现在可以和 Fcitx 5 使用。具体配置方式可以参考之前的一篇博客。而特立独行的 GNOME 则采用了 IBus 的 DBus 协议作为程序和 Compositor 的协议,间接导致我不得不在 Fcitx 5 里实现 IBus 的 DBus 协议。Fcitx 5 做到了完全支持所有现存的 Compositor 和输入法之间的协议支持。所以不要说什么 Fcitx 不支持,根本不是 Fcitx 这一边的问题。

zwp-input-method 版本westonmutter(GNOME Shell)kwinwlroots(sway等)
v1
v2
zwp-input-method 支持情况

让话题回到 Chrome 的情况上来。Chrome 早在 2018年就实现了 text-input-v1 的支持,后续虽然有 text-input-v3 的支持请求,但并没有任何后续动作。前面我们说道,支持 text-input-v1 的 Compositor 有且仅有 weston,几乎等于是没有桌面支持。Ozone 作为抽象,没有使用 Gtk 作为图形栈,因此也就没有自动获得使用 im module 的能力。而在 2021 年,他们添加了 gtk im module 的支持,但是仅限启用 gtk 4 的情况。尽管他们添加了这样的支持,由于他们完全没有用 Gtk 作为图形栈实现图形显示,因此他们的实现仅有部分能正常工作。主要体现在一些按键处理,以及输入法窗口弹出位置上。这里为了解释发生问题的原因,再稍微介绍一下相关的 gtk im module 的工作流程。gtk im module 需要程序调用对应的 API gtk_im_context_set_client_widget 来告知程序当前是哪个 Widget。而对于完全没有使用 Gtk 作为图形栈的 Ozone 来说,他们没有这样一个 GtkWidget 可以传递给 gtk im module。因此,他们目前的实现就是创建一个从不显示的 dummy gtk window,作为传递给这个 API 的参数。这里略微对比一下架构不同的 Firefox,Firefox 是采用 Gtk 作为他们的窗口的 API 的,因此 Firefox 的窗口是一个货真价实的 GtkWindow,而 Ozone 的 Window 则是他们自己直接使用 wayland API 创建的,和 Gtk 完全没有关系。而他们创建的 Dummy window 是完全无法用于让输入法弹出窗口定位在正确位置上的。甚至于由于这个窗口完全不被显示,Fcitx 5 im module 的 client side input panel 技术受限于 Wayland 的限制(xdg_popup 的父窗口必须被显示才能显示)甚至无法显示。而即使考虑是否能使用 gtk 自己的 text-input-v3 的 im module,也因为这个 dummy gtk window 对应的 wl_surface 不被显示,因此不会获取焦点(和 text-input 绑定的 surface 必须获得焦点才能使用 text-input 进行输入法相关操作),也无法正常工作。也就是说,采用 gtk im module 在 Wayland 下 Chrome 正常使用输入法的道路是「几乎」被堵死的。存在两个问题 1、输入事件处理栈并非 Gtk,一些输入法 API (Forward Key,但是是小问题)并不能正常使用 2、图形栈并非 Gtk,弹出窗口的显示既无法使用 Gtk 自身的 text-input-v3 实现,也无法使用 fcitx 5 im module 的 client side input panel。

对于 Fcitx 5 的现状来说,在使用 Chrome + Ozone Wayland + fcitx 5 im module 的情况会 Fallback 到 Fcitx 5 的 X11 输入窗口。也许你有疑问,为什么要 Fallback 到 X11 的输入窗口,不能用 Wayland 窗口显示吗?因为 Wayland 完全无法指定要把窗口显示在哪里,而 Gtk im module 尽管不能获得 Gtk Widget,但好歹能获得一个相对浏览器窗口的坐标。尽管把窗口完全显示在正常位置需要获得窗口自身位置,但如果在「单屏幕」,「窗口最大化」的前提下,这个不完全的相对坐标能够利用 XWayland「恰好」把窗口显示在一个差不多的位置上,总比随机显示在不知道哪里要强得多。

弹出窗口位置能够相对正常显示的唯一的情况,则是 Chrome + GNOME + Fcitx im module + Kimpanel 的组合。这里稍微再讲解一下 Kimpanel 的显示窗口位置逻辑帮助理解为什么这个组合可以工作。Fcitx im module 获取的坐标位置,根据 im module 获取的当前显示服务器类型,会针对 Wayland 额外设置一个标记「Relative/相对」,表示这个坐标是相对当前窗口的坐标。而 GNOME 上刚好运行在 Mutter 同一个进程的 GNOME 插件,则可以获得当前激活窗口的坐标。因此 Kimpanel 如果看到「相对坐标」,就会请求当前窗口坐标然后加上相对坐标来显示输入法弹出窗口。而反过来,对于 KDE Kimpanel 的情况,KWin 和 Plasma 在不同进程的情形,则拿着一个相对坐标束手无策,只能「假装」它是绝对坐标移动一下。而对 KDE Plasma 一个刚刚好的巧合是,Plasma 自身是占用全部屏幕的全屏窗口,因此如果拿到绝对坐标它是可以任意的移动窗口位置的。

综上所述,当前 Chrome 如果要在 Wayland 下使用输入法,各种桌面的组合和实际效果如下:

1、weston + chrome –enable-wayland-ime ,完美支持

2、GNOME + fcitx im module + chrome –gtk-version=4 + kimpanel,支持,但坐标似乎有些小偏移量问题(疑似和边框大小有关)

3、非GNOME,或者不使用 Kimpanel 的 GNOME + fcitx im module + chrome –gtk-version=4 可以输入,但窗口位置不对。

4、chrome Xwayland,完美支持(或者说和 X11 支持程度一致)

而根据 Chrome 当前架构设计,想要完美支持大部分 Linux 桌面的道路只有一条,就是原生支持 text-input-v3 。事实上,考虑已经有 text-input-v1 的实现情况下,代码应该不是很难写。所以如果想要让 Chrome 听见你的呼声,顶这个 bug 就对了 https://bugs.chromium.org/p/chromium/issues/detail?id=1039161

顺便,这个问题也对 electron on wayland 适用。

最后说一些不算解决方案的解决方案,如果你只是想用 chromium 的网页渲染引擎,你可以考虑一些基于 QtWebEngine 的浏览器,例如 https://www.falkon.org/ QtWebEngine 的输入法实现是对接给 Qt 的,可以完全正常在 Wayland 下使用,但缺点也明显,就是不支持 Web Extensions,但 falkon 内置了一些常用功能如油猴 adblock,所以没有复杂要求也可以考虑使用。或者也可以换成 Firefox,它的 Wayland 下输入法支持很好。

P.S. 最后的最后 Fcitx 5 能对这件事做什么?什么也做不了。这不是 Fcitx 5 的 Bug。我是想不到目前有任何改动属于 Fcitx 项目代码的方式能够完美支持 Chrome。

如果非要让「我」力所能及支持点什么的话,1、可能就是给 KWin/Plasma 写一个Wayland 私有协议,允许把窗口移动到相对当前活动窗口的坐标位置上去给 Kimpanel 用。2、或者加回 KWin 删掉了的「没人用」的text-input-v1 支持。说实话,这两种如果写了都是技术债,第一个可能还有点用(通用意义上),但我也并非什么 KWin 的专家。就像我之前说的,我一个臭写输入法的,怎么就去开发 Compositor 去了。

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

5 Responses to Chrome/Chromium 今日 Wayland 输入法支持现状

  1. Firefox 100.0 Android 12

    Firefox 用户情绪稳定 (x

  2. amazingfate says:
    Google Chrome 101.0.4951.67 Windows 10 x64 Edition

    我这边armbian jammy版本,chromium 101.4951.15是可以正常使用fcitx5的

  3. nullizer says:
    Firefox 100.0 GNU/Linux x64

    Chrome问题太多了,何止输入法,我不明白为什么他们不实现中键自动滚动这种基本功能,字体渲染也很难看

  4. Kiolygenius says:
    Firefox 100.0 GNU/Linux x64

    KDE Wayland 下用 Visual Studio Code –gtk-version=4 直接无法启动,检测到gtk 2/3 不能在同一个进程同时使用2/3和4版本。然后写代码就没法中文注释了。

  5. 赛博胖次 says:
    Google Chrome 102.0.0.0 Mac OS X  10.15.7

    > 3、非GNOME,或者不使用 Kimpanel 的 GNOME + fcitx im module + chrome –gtk_version=4 可以输入,但窗口位置不对。

    这个是不是仅限支持 zwp_input_method_v1 的wm?我尝试 sway-im-git (带上了input_method_v2 popups 布丁 https://github.com/swaywm/sway/pull/5890 ),wayland 应用下输入很顺滑,但 chrome/electron 里仍然看不到任何输入法(甚至切换输入法都没任何反应)。不确定是否符合预期…

    btw –gtk_version 应该是 –gtk-version

Leave a Reply

Your email address will not be published.

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