docs/社区开发指南/openKylin系统输入法适配指南.md

16 KiB
Executable File
Raw Blame History

麒麟操作系统输入法适配指南

1. 背景

本文档提供了麒麟操作系统中内置的fcitx5输入法框架的简介以及输入法引擎适配到fcitx5所需要做的工作的详细介绍。

2. fcitx5输入法框架

2.1 简介

2.1.1 整体设计架构

fcitx5输入法框架采用插件化设计。在该设计中包含一个fcitx5输入法框架服务和若干个插件动态库。下面介绍一下主要模块。

2.1.1.1 fcitx5输入法框架服务

fcitx5输入法框架服务是由fcitx5可执行程序提供的一个服务。该服务负责加载各个插件动态库并与其他模块进行通信。

2.1.1.2 前端插件模块

fcitx5输入法框架拥有多个前端插件模块分别为dbusfrontend, fcitx4frontend, ibusfrontend, waylandim, xim。用于兼容不同的系统环境和应用。

2.1.1.2.1 dbusfrontend

dbus前端插件是fcitx5自己的协议实现的Qt/GTK输入法模块使用该前端插件和fcitx5进行通信。

2.1.1.2.2 fcitx4frontend

fcitx4前端插件提供了对使用了fcitx4 dbus协议的输入法模块的应用的支持。

2.1.1.2.3 ibusfrontend

ibus前端插件实现了ibus协议。

2.1.1.2.4 waylandim

waylandim实现了Wayland提供输入法协议的服务端协议。

2.1.1.2.5 xim

xim实现了X11的输入法协议的服务端协议。

2.1.1.3 UI插件模块

fcitx5输入法框架提供了三种UI插件分别是classic UI插件kimpanel UI插件virtualkeyboard UI插件。

2.1.1.3.1 classic UI

fcitx5默认使用并且已经集成在输入法框架中的UI插件。

2.1.1.3.2 kimpanel UI

fcitx5使用的物理键盘输入窗口UI代理插件。适配时需要实现kimpanel服务端。该插件使用DBus接口和服务端进行通信。

2.1.1.3.3 virtualkeyboard UI

fcitx5使用的虚拟键盘UI代理插件。适配时需要实现虚拟键盘服务端。该插件使用DBus接口和服务端进行通信。

2.1.1.4 输入法引擎插件模块

fcitx5输入法框架定义了输入法引擎插件使用的接口。任何输入法引擎只要实现了该接口并且按照一定的格式将输入法引擎对象导出那么fcitx5输入法框架可以正确加载并使用该输入法引擎。

2.1.2 基本工作原理

fcitx5输入法框架多个前端插件模块实现了支持多种输入法协议和GUI框架包括XIM、Wayland、ibus等输入法协议和Qt、GTK等GUI框架。

其中dbus前端插件dbus frontend模块负责跟Qt和GTK等GUI框架的输入法插件进行dbus通信。

下面以Qt5应用程序为例简要介绍一下Qt5程序通过fcitx5输入法框架与输入法引擎的交互过程。基本原理示意图如下所示

inputmethod.png

2.1.2.1 Qt5输入法模块

fcitx5-qt项目实现了Qt5定义的输入法接口以及跟fcitx5输入法框架的dbus前端插件进行通信的接口使得Qt5程序中的事件可以发送到fcitx5输入法框架中

2.1.2.2 dbus前端插件

通过dbus接收从Qt或GTK程序发送过来的dbus信号或者调用

2.1.2.3 fcitx5输入法框架

dbus前端插件将事件或函数调用进行若干处理后调用fcitx5输入法框架中的函数一般是调用InputContext对象的方法向fcitx5输入法框架发送一个事件

2.1.2.4 UI代理插件

fcitx5输入法框架支持多种UI显示方式包括使用X11 API的classic UI插件和使用远程显示服务的kimpanel插件。示意图中的UI代理插件说的就是kimpanel插件而impanel则是相应的远程显示服务。该服务可以显示物理键盘输入法的输入窗口。

2.1.2.5 输入法UI服务

如果输入法框架使用了UI代理插件则UI代理插件会与对应的输入法UI服务进行通信。

2.1.2.6 输入法引擎插件

fcitx5输入法框架收到按键事件后经过若干处理后会调用实现了fcitx5定义的输入法引擎API InputMethodEngine的输入法引擎插件的函数。通过插件中的函数实现与输入法引擎服务的通信

2.1.2.7 输入法引擎

输入法引擎实现了输入法的真正逻辑。输入法引擎既可以直接封装在输入法引擎插件中也可以通过IPC通信的方式实现输入法引擎和输入法引擎插件之间的通信。

2.2 对物理键盘输入法引擎的支持

2.2.1 UI支持

fcitx5提供了基于DBus协议的物理键盘输入法UI代理插件kimpanel。该模块位于fcitx5/src/ui/kimpanel目录。

2.2.1.1 DBus服务

2.2.1.1.1 DBus服务名称

org.kde.kimpanel.inputmethod

2.2.1.1.2 DBus对象路径

/kimpanel

2.2.1.1.3 DBus接口名称

org.kde.kimpanel.inputmethod

2.2.1.2 DBus信号

kimpanel提供的dbus信号可以由kimpanel进行调用从而实现从kimpanel到impanel的通信。impanel UI服务负责响应这些信号。

2.2.1.2.1 ExecDialog

显示对话框

2.2.1.2.2 ExecMenu

显示菜单

2.2.1.2.3 RegisterProperties

注册菜单项

2.2.1.2.4 UpdateProperty

更新菜单项

2.2.1.2.5 RemoveProperty

移除菜单项

2.2.1.2.6 ShowAux

是否展示Aux提示文本

2.2.1.2.7 ShowPreedit

是否展示预编辑串

2.2.1.2.8 ShowLookupTable

是否展示候选结果

2.2.1.2.9 UpdateLookupTableCursor

更新输入位置光标

2.2.1.2.10 updatePreeditCaret

更新预编辑串光标

2.2.1.2.11 UpdatePreeditText

更新预编辑文本

2.2.1.2.12 UpdateAux

更新aut辅助文本

2.2.1.2.13 UpdateSpotLocation

2.2.1.2.14 UpdateScreen

2.2.1.2.15 Enable

启用或者禁用输入窗口

2.2.1.3 DBus方法

kimpanel提供的dbus方法可以由impanel UI服务进行调用从而实现从impanel到kimpanel的通信

2.2.1.3.1 Exit

退出fcitx5输入法框架服务

2.2.1.3.2 ReloadConfig

重启fcitx5上输入法框架服务

2.2.1.3.3 Configure

启动fcitx5配置工具

2.2.1.3.4 LookupTablePageUp

候选结果向上翻页

2.2.1.3.5 LookupTablePageDown

候选结果向下翻页

2.2.1.3.6 SelectCandidate

选择指定候选结果

2.2.1.3.7 PanelCreated

物理键盘输入法输入窗口创建成功

2.2.1.3.8 PanelCreated2

物理键盘输入法输入窗口创建成功

2.2.2 输入法引擎支持

fcitx5提供了输入法引擎APIInputMethodEngine、InputMethodEngineV2、InputMethodEngineV3和InputMethodEngineV4。其中InputMethodEngineV4增加了对虚拟键盘输入法按键事件的支持。

2.2.2.1 输入法引擎API

2.2.2.1.1 keyEvent

功能:输入法处理按键事件的主要函数。

参数const InputMethodEntry &entry,KeyEvent &keyEvent

返回值类型void

2.2.2.1.2 activate

功能:激活引擎

参数

返回值类型

2.2.2.1.3 deactivate

功能:失活引擎

参数

返回值类型

2.2.2.1.4 reset

功能:重置

参数

返回值类型

2.2.2.1.5 filterKey

功能处理key事件未被其他地方处理的key事件

参数input method entrykey event

返回值类型void

实现最简单的物理输入法只需要重写keyEvent函数即可。

2.3 对虚拟键盘输入法引擎的支持

2.3.1 UI支持

fcitx5提供了基于DBus协议的虚拟键盘UI插件virtualkeyboard UI在fcitx5/src/ui/virtualkeyboard中。该插件的相关信息和接口如下所示。

2.3.1.1 DBus服务

2.3.1.1.1 DBus服务名称

org.fcitx.Fcitx5.VirtualKeyboardBackend

2.3.1.1.2 DBus对象路径

/virtualkeyboard

2.3.1.1.3 DBus接口名称

org.fcitx.Fcitx5.VirtualKeyboardBackend1

2.3.1.2 DBus信号

2.3.1.2.1 ShowVirtualKeyboard

功能:向虚拟键盘发送的显示信号。

参数:无。

2.3.1.2.2 HideVirtualKeyboard

功能:向虚拟键盘发送的隐藏信号。

参数:无。

2.3.1.2.3 UpdatePreeditCaret

功能:向虚拟键盘发送的设置预编辑文本光标位置信号。

参数:

int preeditCursor光标所在位置的编号。

2.3.1.2.4 UpdatePreeditArea

功能:向虚拟键盘发送的设置预编辑文本信号。

参数:

string preeditText预编辑文本。

2.3.1.2.5 UpdateCandidateArea

功能:向虚拟键盘发送的设置候选词信号

参数:

vectorstd::string &candidateTextList当前页的候选词集合每个元素都是一个候选词。

bool hasPrev是否存在上一页候选词。

bool hasNext是否存在下一页候选词。

int pageIndex当前候选词页的页码。

2.3.1.2.6 NotifyIMActivated

功能:向虚拟键盘发送当前输入法激活信号。

参数:

string uniqueName当前输入法的名称。

2.3.1.2.7 NotifyIMDeactivated

功能:向虚拟键盘发送当前输入法失活信号。

参数:

string uniqueName当前输入法的名称。

2.3.1.2.8 NotifyIMListChanged

功能:向虚拟键盘发送当前输入法列表改变通知信号。

参数:无。

2.3.1.3 DBus方法

2.3.1.3.1 ProcessKeyEvent

功能:接收虚拟键盘发送的按键事件,将其转发给输入法框架。

参数:

uint32_t keyval, 当前键盘布局下当前按键的所代表的值英文时为按键对应的ASCII码。

uint32_t keycode, 所有键盘布局中当前按键的唯一标记值在Linux系统中定义。

uint32_t state, 按键的修饰符状态如ShiftCaps Lock等按键详情可见fcitx5/src/lib/fcitx-utils/keysym.h。

bool isRelease, 按键是否按下true为抬起false为按下。

uint32_t time, 按键按下时的时间戳默认为0。

2.3.1.3.2 ProcessVisibilityEvent

功能:接收虚拟键盘发送的虚拟键盘可见性事件,更新后端模块中的可见性信息。

参数:

bool visible, 虚拟键盘的可见性true为正在显示false为已经隐藏

2.3.1.3.3 SelectCandidate

功能:接收虚拟键盘选择的候选词序号,上屏该候选词。

参数:

int index, 用户选择的候选词序号。

2.3.1.3.4 PrevPage

功能:接收虚拟键盘发送的候选词翻页请求,切换到上一页候选词。

参数:无。

2.3.1.3.5 NextPage

功能:接收虚拟键盘发送的候选词翻页请求,切换到下一页候选词。

参数:无。

2.3.2 输入法引擎支持

fcitx5的输入法引擎InputMethodEngineV4增加了虚函数virtualKeyboardEventImpl提供了对虚拟键盘输入法按键事件的支持相关代码在fcitx5/src/lib/fcitx/inputmethodengine中。

如果输入法引擎想要提供对虚拟键盘按键事件的支持则需要实现InputMethodEngineV4接口。否则只需要考虑实现其他三个用于物理键盘输入法引擎的接口即可。

3. 适配fcitx5输入法框架

3.1 物理键盘输入法引擎适配

3.1.1 UI适配

fcitx5提供了默认的物理键盘输入法输入窗口UI在不考虑特殊的客户端侧输入法UI的情况下可以简单的划分为两种classic UI和kimpanel UI。

3.1.1.1 classic UI

该UI是fcitx5提供的使用底层API(X11wayland)实现的输入窗口UI。

3.1.1.2 kimpanel UI

该UI是fcitx5提供的输入窗口UI代理其定义了若干dbus API可以用来跟远端的物理键盘输入法UI服务进行通信。该模块最初用于解决Ubuntu上输入法窗口被全局搜索界面覆盖导致的无法看到输入窗口的问题而提供的。

为了简化适配第三方输入法可以考虑直接适配该UI代理模块定义的dbus接口即可。

如果想要提供更全方位的定制则还需要考虑提供跟kimpanel类似的UI代理模块。

3.1.2 输入法引擎适配

3.1.2.1 输入法配置文件编写

配置文件分为插件配置文件和输入法配置文件,每个配置文件中字段含义不同。

插件配置文件:插件配置文件安装在插件目录/share/fcitx5/addon/下。

举例拼音输入法插件配置文件:

[Addon]
Name[ca]=Pinyin
Name[da]=Pinyin
Name[de]=Pinyin
Name[he]=פיניין:
Name[ko]=병음
Name[ru]=Пиньинь
Name[zh_CN]=拼音
Name=Pinyin
Category=InputMethod
Version=5.0.11
//对应的拼音输入法so为libpinyin.so
Library=libpinyin
Type=SharedLibrary
OnDemand=True
Configurable=True

//插件依赖
[Addon/Dependencies]
0=punctuation

输入法配置文件:输入法配置文件保存在输入法目录/share/fcitx5/inputmethod/下。

举例拼音输入法引擎配置文件:

[InputMethod]
Name[ca]=Pinyin
Name[da]=Pinyin
Name[de]=Pinyin
Name[he]=פיניין:
Name[ko]=병음
Name[ru]=Пиньинь
Name[zh_CN]=拼音
Name=Pinyin
//拼音输入法对应的icon名称
Icon=fcitx-pinyin
Label=
LangCode=zh_CN
//输入法对应的插件
Addon=pinyin
//是否支持自定义
Configurable=True

3.1.2.2 工程CMakeLists文件编写

工程文件CMakeLists文件定义了输入法源码文件的编译行为。包括编译过程中链接的库以及配置文件安装路径等等。以pinyin输入法为例

#pinyin
add_library(pinyin SHARED pinyin.cpp)
target_link_libraries(pinyin PRIVATE Fcitx5::Core)
set_target_properties(pinyin PROPERTIES PREFIX "")
install(TARGETS pinyin DESTINATION "${FCITX_INSTALL_LIBDIR}/fcitx5")

#拼音输入法插件配置文件转换与安装
#将pinyin-addon.conf.in输出为pinyin-addon.conf
configure_file(pinyin-addon.conf.in pinyin-addon.conf) 
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pinyin-addon.conf" RENAME quwei.conf DESTINATION "${FCITX_INSTALL_PKGDATADIR}/addon")

#定义了拼音输入法引擎配置文件安装路径
# Input Method registration file
install(FILES "pinyin.conf" DESTINATION "${FCITX_INSTALL_PKGDATADIR}/inputmethod")

3.1.2.3 实现物理输入法引擎接口

输入法引擎部分适配即要重写定义的引擎相关的接口其中最主要的接口是InputMethodEngine::keyEvent()。以pinyin输入法为例

继承AddonFactory插件工厂类创建一个拼音输入法引擎插件类

class PinyinEngineFactory : public AddonFactory {
public:
    AddonInstance *create(AddonManager *manager) override {
        registerDomain("fcitx5-chinese-addons", FCITX_INSTALL_LOCALEDIR);
        return new PinyinEngine(manager->instance());
    }
};

拼音引擎插件类继承InputMethodEngineV3实现相关的接口功能。如activate()、deactive()、keyEvent()和reset()接口等

class PinyinEngine final : public InputMethodEngineV3 {
public:
    PinyinEngine(Instance *instance);
    ~PinyinEngine();
    Instance *instance() { return instance_; }
    void activate(const InputMethodEntry &entry,
                  InputContextEvent &event) override;
    void deactivate(const InputMethodEntry &entry,
                    InputContextEvent &event) override;
    void keyEvent(const InputMethodEntry &entry, KeyEvent &keyEvent) override;
    void reset(const InputMethodEntry &entry,
               InputContextEvent &event) override;
   ...
  };

3.2 虚拟键盘输入法引擎适配

3.2.1 UI适配

fcitx5提供了默认的虚拟键盘输入法输入窗口UI代理模块virtualkeyboard UI。

为了简化适配第三方输入法可以考虑直接适配该UI代理模块定义的dbus接口即可。

如果想要提供更全方位的定制则还需要考虑提供跟virtualkeyboard类似的UI代理模块。

3.2.2 输入法引擎适配

虚拟键盘输入法引擎适配与物理键盘键盘输入法引擎适配基本类似差别仅在于虚拟键盘输入法引擎需要实现InputMethodEngineV4类中的virtualKeyboardEventImpl虚函数。

参考文档

输入法引擎相关代码文档:https://codedocs.xyz/fcitx/fcitx5/classfcitx_1_1InputMethodEngine.html

实现一个最简单输入法:https://fcitx-im.org/wiki/Develop_an_simple_input_method