Skip to content

About

Linux port and Fcitx 5 integration for the WeType Android input engine

Resources

Stars

253 stars

Watchers

0 watching

Forks

Latest commit

 

History

59 Commits

Folders and files

Repository files navigation

WeType Linux

在 Linux 上通过 Fcitx 5 使用微信输入法(WeType)引擎。引擎是 Android ARM64 版本,运行在 Android 自己的 C 运行时(AOSP bionic)上:x86_64 主机通过 QEMU user 模式运行,ARM64 主机原生运行,不需要 QEMU。

非官方项目,与腾讯无关,也未获其认可。WeType、微信输入法、微信是腾讯的商标。使用 WeType 引擎须遵守腾讯的相关条款。

本仓库和 AppImage 只包含本项目自己的代码,以及可再分发的运行时(取自 AOSP 系统镜像的 bionic;x86_64 版另含 QEMU),不包含任何 WeType 文件。安装时会从腾讯官方服务器下载 WeType 3.5.4 APK,校验 SHA-256 后在本机打补丁,思路类似 Minecraft 的 Paper。

功能与限制

本项目只把微信输入法的 Android 引擎接入 Fcitx 5,不是官方客户端的完整移植。当前能力如下:

功能 状态 说明
键盘拼音输入、中文候选 支持 候选由 WeType 3.5.4 引擎产生
拼音纠错(乱序、键邻、漏字等容错候选) 支持 会话配置按官方客户端默认值传入(enable_local_correction 与 InputAugmenter 的 exchange/keyboard_neighbour/insert_at_middle/skip)
emoji/颜文字候选 支持 按官方默认开启(local_most_likely_config / local_process_input_config 的 emoji 开关)
数字、空格、鼠标选词及部分选词 支持 部分选词后可继续选择剩余拼音的候选
候选翻页、全局候选数量 支持 每页 1–10 个,跟随 Fcitx5 全局配置;第 10 个用 0 选择
本地选词学习及持久化 支持 学习数据保存在本机;重启后可复用
候选英文释义 可选 用户提供本地 TSV 词表,仅影响显示,不改变上屏内容
跨设备剪贴板、跨设备粘贴 未实现 未接入跨设备通信或官方剪贴板功能;不影响系统本地复制粘贴
官方账号登录、云端词库及跨设备同步 未接入 本项目没有提供登录或同步接口,不能使用官方客户端的同步流程
中文状态全角标点(除 ` 外的全部 ASCII 符号) 支持 引号自动配对,\ 出 、;仅光标紧跟数字时 . , 保持半角
Shift + 字母直出大写 支持 空闲态 Shift+A 上屏 A;组词中仍按小写拼音

本地词库和学习数据的保存不等于云同步。学习数据默认位于 ~/.local/share/wetype-ime/dict,设置了 XDG_DATA_HOME 时使用 $XDG_DATA_HOME/wetype-ime/dict;高级调试可用 WETYPE_WORK_DIR 覆盖。

发布两种 AppImage:WeTypeIME-Engine-x86_64.AppImage(x86_64 Linux,自带 QEMU)和 WeTypeIME-Engine-aarch64.AppImage(ARM64 Linux,原生运行,不含 QEMU)。Fcitx5 插件在 Ubuntu 24.04 上随包构建,要求宿主有 glibc ≥ 2.38 和 Fcitx5 5.1.x(libFcitx5Core.so.7);更旧的发行版(如 Ubuntu 20.04)请用 fcitx5-wetype/build.sh 按本机 Fcitx5 从源码构建插件。默认在缺少有效 APK 缓存时联网下载;也可通过 --apk 使用已下载的 APK。英文释义是本地查表,不进行网络查询。上述功能清单不构成对专有引擎内部网络行为的保证。

安装

先安装依赖(下载、校验、解包、补丁都在 python3 标准库内完成,无需 curl/unzip):

sudo apt install python3                        # Debian / Ubuntu
sudo dnf install python3                        # Fedora
sudo pacman -S --needed python                  # Arch

ARM64 主机还需要 patchelf(安装时把 harness 的 ELF 解释器指向包内的 bionic linker64,之后原生运行,不改动 /system):

sudo apt install patchelf                    # Debian / Ubuntu;Fedora、Arch 同名

然后运行:

./WeTypeIME-Engine-$(uname -m).AppImage install       # 安装到 ~/.local;用 sudo 则安装到 /usr

安装完成后重启 Fcitx5,并在输入法配置中添加“微信拼音”。

候选翻页:组词时 - =(以及 PgUp/PgDn、↑/↓)按整页翻页,到达边界也不会把这两个字符漏进文档;每页候选数跟随 Fcitx5 全局设置“候选词数量”(1–10,默认 5),候选前显示的数字即选词键(每页 10 个时第 10 个为 0)。

其他命令:

./WeTypeIME-Engine-$(uname -m).AppImage install --apk 文件   # 使用已下载的 APK(仅支持 3.5.4,其他版本未经测试,会被拒绝)
./WeTypeIME-Engine-$(uname -m).AppImage uninstall            # 卸载(保留词库和用户数据)
./WeTypeIME-Engine-$(uname -m).AppImage demo nihao           # 命令行测试候选词

APK 约 214 MB,只下载一次,缓存在 ~/.cache/wetype-ime。用户学习数据在 ~/.local/share/wetype-ime。

从源码构建

x86_64 AppImage 的构建环境为 x86_64 的 Debian / Ubuntu:

sudo apt install build-essential cmake libfcitx5core-dev file qemu-user-static \
  e2fsprogs unzip python3 curl

harness 使用 Android NDK r27c(27.2.12479018)交叉编译为 Android ARM64/API 28;Fcitx5 插件仍由宿主 C++ 编译器原生构建,无需 Android Studio、Java 或完整 Android SDK。

bash scripts/prepare_ndk.sh  # 从 Google 下载到 .deps/tools/,按官方校验值检查;后续复用缓存
export ANDROID_NDK_HOME="$PWD/.deps/tools/android-ndk-r27c"

也可用 ANDROID_NDK_HOME 指向已有兼容 NDK;不设置时构建脚本回落到上述项目缓存。CI 固定使用 r27c。构建时还会下载 AOSP Android 9 的 ARM64 模拟器系统镜像(约 407 MB,缓存在 .deps/aosp/),校验 SHA-256 后提取 bionic 运行时。NDK 只有 x86_64 Linux 主机版,所以 harness 与 bionic 运行时总是在 x86_64 主机上构建;ARM64 AppImage 复用这些产物在 ARM64 主机上打包(见下)。

scripts/e2_img.sh        # 构建插件、harness 并打包 AppImage(不需要 APK)

没有 FUSE 时(容器、虚拟机)请设置 APPIMAGE_EXTRACT_AND_RUN=1。打包时如果发现任何来自 APK 的文件,会拒绝打包。

ARM64 AppImage在 ARM64 主机上打包:先在 x86_64 主机上构建并导出 harness 与运行时,再到 ARM64 主机上用同一份源码打包。CI 自动完成这两步。

# x86_64 主机
bash scripts/20_build.sh
tar -cf engine-runtime.tar runtime/libandroid.so runtime/sysroot harness/jinterop

# ARM64 主机(需要 build-essential cmake libfcitx5core-dev file patchelf curl)
tar -xf engine-runtime.tar
WETYPE_SKIP_NDK_BUILD=1 scripts/e2_img.sh        # 生成 WeTypeIME-Engine-aarch64.AppImage,包内不含 QEMU
scripts/smoke_native_harness.sh AppDir/usr/lib/wetype-ime/arm64   # 原生冒烟测试,不需要 APK

在源码树中直接调试引擎:

scripts/20_build.sh          # 用 NDK 构建 harness 和 libandroid.so 替身,提取 bionic 到 runtime/sysroot
scripts/prepare_assets.sh    # 下载并校验 APK 到 .deps/
scripts/10_patch_libs.sh     # 拷贝 APK 中的引擎库并打补丁,输出到 runtime/

插件日志默认写入 $XDG_STATE_HOME/wetype-ime/harness.log(未设置时 ~/.local/state/wetype-ime/harness.log),超过 16 MiB 自动轮转为 .1;设 WETYPE_HARNESS_LOG 可改到别处(如 /dev/null 关闭日志)。

可无桌面验证已安装的引擎(使用临时学习目录,不修改实际用户词库):

python3 scripts/test_bionic_daemon.py --engine-dir "$HOME/.local/lib/wetype-ime/arm64" --idle-seconds 85

ARM64 主机上加 --native(不经 QEMU;回归使用临时拷贝并用 patchelf 设置解释器,不改动已安装的 harness)。ARM64 与 x86_64 的候选延迟对比见 docs/benchmarks/arm64-native-vs-qemu.md。

此回归覆盖候选、部分选词、学习、重置、长空闲恢复及重启持久化。插件及词表解析测试使用 cmake -S fcitx5-wetype -B build && cmake --build build && ctest --test-dir build --output-on-failure。

需要验证真实候选窗绘制与应用上屏时,可在无头主机上运行 Xvfb + GTK3 的 视觉 E2E:LIB=/path/to/libfcitx5-wetype.so WETYPE_ENGINE_DIR=/path/to/arm64 bash fcitx5-wetype/e2e/run_visual_e2e.sh。测试会保存候选窗、翻页与上屏截图,不需要完整桌面环境。

可选候选英文释义

将 UTF-8 词表放到 ~/.local/share/wetype-ime/glossary-en.tsv,设置了 XDG_DATA_HOME 时则放到 $XDG_DATA_HOME/wetype-ime/glossary-en.tsv。重启 Fcitx5 后加载,无网络请求。词表格式为 中文词<TAB>[词性. ]英文释义,例如:

你好	n. hello
世界	n. world

兼容 qingjian 的 glossary-en.tsv 格式;本仓库不附带词表。匹配到的释义以斜体追加在候选后,仅供展示,不改变候选顺序、选词键或上屏内容。缺少词表或未匹配到词条时,候选显示不变。候选数量仍跟随 Fcitx5 全局配置。

英文释义只影响展示;标点与异步空格规则见下节。

中文状态标点

  • 微信拼音就是中文输入状态,所以除 ` 之外的每一个 ASCII 符号都上全角。前一个词是英文单词也不会退回半角;需要半角符号请切换到英文键盘。
  • 有中文专属写法的用中文标点,其余用对应的全角字符(U+FF01–FF5E):
键 上屏 键 上屏 键 上屏
, . , 。 ? ! ? ! : ; : ;
\ 、 ( ) ( ) [ ] 【 】
< > 《 》 { } { } " ' “ ” ‘ ’
- _ - _ + = + = * / * /
# $ # $ % & % & @ ^ @ ^
~ | ~ | ` 反引号原样
  • 引号按开/闭配对:同一个输入上下文里第一次按 " 出 “,第二次出 ”,单引号同理。
  • 正文里唯一的例外:光标紧跟数字时只有 . 与 , 保持半角,3.14、1,000 不会被写成 3。14;3( 这类仍是全角。小键盘那一排数字同样算数字,数字后隔着空格仍按紧跟数字处理。
  • 组词时按标点,宽度依据本次实际提交的候选或原始拼音判断,不使用上一条提交的语言。
  • 周围文本只在应用更新时刷新;刚提交的文本不会被尚未更新的旧周围文本覆盖。不同输入上下文的状态不共享。
  • 应用标记的密码、邮箱、URL、数字等结构化字段一律保留半角;快捷键(如 Ctrl+,)与按键释放仍透传。
  • ` 保持原样是为了 markdown、shell 引用和代码;\ 因此成为顿号键,写 LaTeX 命令或 Windows 路径请切英文键盘。- = 在组词时仍用于翻页(只在空闲态才上全角)。没有接入账号或网络查询。

Shift + 字母直出大写

  • 没有组词时按住 Shift 打字母,大写字母直接上屏,不会折进拼音缓冲:DNA、GDP、Hello 都能在中文状态里直接打完。
  • 一个大写字母上屏后接着打的小写字母照常组词;要整段英文请切换到英文键盘。
  • 只在空闲状态生效:组词途中按 Shift 仍当作小写拼音,避免候选框还挂着就往文档里插字母。
  • CapsLock 不算按住 Shift(大写键但 Shift 位为空时仍走拼音);Ctrl/Alt/Super 组合优先当快捷键。按键释放事件保持透传。

异步空格选词

  • 拼音的最新候选尚未返回时,空格会等待该次候选,而不是立即提交原始拼音;旧前缀预览不能代替当前候选。
  • 等待期间后续可打印按键及释放按顺序排队。一次空格只选择一个候选片段;连续空格可继续选择剩余拼音,组词结束后的空格正常透传。
  • 退格先删除排队的最新输入;队列没有输入时删除拼音,并继续等待编辑后的候选。Esc/reset 取消整个未提交组词。
  • Enter、无候选或恢复失败时按原文提交,包括已输入的空格与后续文字。等待最多 5 秒,队列最多 256 个按键事件;到限同样原文提交,不静默丢字。
  • 导航或快捷键先结束等待、提交原文,再透传,避免后续文字落到移动后的光标处。切换输入法也保留完整原文;切换应用沿用不额外上屏的行为,预编辑包含排队文字,最终是否上屏由前端处理。

可在私有 D-Bus 与临时配置中运行回归(不修改桌面输入法):

WETYPE_ENGINE_DIR=/path/to/engine WETYPE_E2E_KEYBOARD=1 \
WETYPE_E2E_SCRIPT="$PWD/fcitx5-wetype/e2e/pending_space_test.py" \
bash fcitx5-wetype/e2e/run_paging_e2e.sh 5

pending_engine_fixture.py 是仅供隔离测试的协议响应器;用 QEMU_AARCH64 指向它,配合 WETYPE_PENDING_FIXTURE=empty|error|skip|startup-failure 和 pending_failure_test.py 验证确定性失败路径,不代表真实引擎测试。

目录结构

  • fcitx5-wetype/:Fcitx 5 插件
  • harness/:伪造 JNI 环境、驱动引擎的 ARM64 程序
  • shim/:libandroid.so 替身
  • scripts/:下载、补丁、构建、打包和测试脚本

许可证

本项目使用 GPL-3.0-or-later,见 LICENSE;harness/jni.h 取自 AOSP Android 9,来源见 JNI 声明说明,完整 Apache-2.0 许可证 随源码及 AppImage 附带。x86_64 AppImage 内附带的 QEMU(GPL-2.0)和两种 AppImage 内的 AOSP 组件(bionic、liblog、libc++、zlib)的许可说明见镜像内的 usr/share/doc/wetype-ime/THIRD-PARTY.md。WeType 引擎和词库归腾讯所有,不在本许可范围内,本项目也不分发它们。

About

Linux port and Fcitx 5 integration for the WeType Android input engine

Resources

Stars

253 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages