Yes

Keep It Simple, Stupid.

Emscripten IME输入法

Posted at — Nov 4, 2020

2020.11.04:

github上看遍了基于GPU加速的开源GUI库,下载点运行他们的demo,在这些项目中:
1. 在PC平台上支持中文输入法的约有90%
2. 在手机平台上支持中文输入法的约有20%
3. 支持网页平台输入法的为0%

去Emscripten repo上的issue列表里搜索了下IME,发现有人提过这事,官方开发者表示:”we need a mature solution, so ime is not supported”
emmmm.官方也没办法,去google上搜了一圈有没有第三方方案,也没找到,只能自己想办法了

找了下web上直接唤出输入法的函数,没找到。原生的网页文本输入窗不关用什么手机,点一下都是可以出现提示输入的。那么就从这里开始入手。

思路1

  1. 写段HTML创建1个网页文本输入窗
  2. 写段C++ WEB ASM 用于轮询HTML里面的网页文本输入窗是否有文字,有就提取出来

写完发现输入在打字的时候,比如输入:晓,全拼中打字顺序是这样:xiao,实际用C++轮训捕获出来的结果是xiao 晓,程序需要的效果是一个中文字,结果把用户打的东西全记录进去了。

思路2

  1. 写段HTML创建2个网页文本输入窗
  2. 写段JS,JS内加个listener,用于侦听1号文本输入窗输入完成事件,在输入完成的callback里加上一个复制函数,复制自身的文本给2号文本输入窗。
  3. 写段C++ WEB ASM 轮询HTML里面的2号文本输入窗是否有文字,有就提取出来.
  4. 当需要输入法输入的时候,C++内ASM调用getElementById.focus就可以。

测试

实际在PC的FireFox上测试后,发现这样的确工作了,C++在web也能让使用输入法了,并且能捕获输入的文字。

用iPhone的safari打开网页测试时发现,用搜狗打字并不能被C++正确识别到,原来搜狗和标准输入法相比少了触发事件:compositionstart/end,但是它是单次上屏的,不会出现xiao晓的现象。 原先的思路是这样,1号窗口触发compositionend事件(输入法文字上屏事件)的时候复制value到2号窗口,给C++捕获。

思路3

修改后思路是这样,设置composing为false,默认关闭用户正在输入法状态,触发compositionstart就设置composing=true,表示用户开始在输入法内打字,触发 compositionend就设置composing=false表示不在打字,同时复制复制value到2号文本框给C++捕获。
为搜狗输入法新增一个hook,就是侦听textInput事件,有任何文本进去都会响应,上面说了,搜狗不会把xiao字母记录进去,且不会触发composition任何事情,所以直接加个if(composing == false) 就拷贝value到2号文本框,给CXX调用就OK了。

再次测试后成功了。

ToDo:
- 无输入法混合输入符号和字母的问题
- 贴两个文本框在页面上太丑的问题 sad.

EOF

一个咸鱼级全硬件加速的GUI项目,一份代码全平台运行,让垃圾C++写自用APP不再困难
在线Demo: uu.rs/app/em.html

Git Repo: https://github.com/Xarvie/chain-3d.git


本文采用 CC BY-ND 4.0 国际许可协议 进行许可,不注明署名无权转载(BY)禁止演绎(ND)