您的位置:首页 > 其它

chromium bug修复记录与心得——TextInputClient setting

2018-02-09 15:46 267 查看
chromium中提供了IME模块实现输入功能,在页面或者UI中需要输入的地方,都使用IME模块来实现,同时,chromium中提供了一个TextInputClient的类,作为输入对象的逻辑表示,在页面和UI各有对其的实现,所以在使用体验上,对页面输入和UI输入是同样的。
从输入的过程来说,要输入,首先就要确定输入的目的,其接口的定义来自于前文提到的类:TextInputClient,在src/ui/base/ime中定义。

TextInputClient中声明了接口,目前在两个类中有实现:
1. TextFiled,此为Aura UI中的组件,属于native UI,实现了TextInputClient的所有接口;
2. RenderWidgetHostViewAura,这个组件对应于网页中的输入框,实现了TextInputClient中的部分接口,本人因此还入过坑,在后文会介绍到。

工作流程:

1. 当有输入框(页面或者UI同样)被focus的时候,从页面首先从WebViewImpl中通过RenderWidget将输入框绑定到IME中,UI也会设置当前的输入框IME中,此时开始等待输入;
2. 当键盘事件到来,IME会判断当前的TextInputClient是否存在,若存在则通过Event获取keyCode, 插入到TextInputClient中,此时分两种情况,一个是按键为字符键,直接调用TextInputClient::InsertChar()完成输入,若为控制键,即enter键、shift键等等,则会匹配控制键,然后实现其控制功能;
3. 针对网页输入时,RenderWidgetHostViewAura::InsertChar() 会通过按键的keyCode构造一个blink事件,这个事件的作用就是将各种平台事件转换为blink中使用的事件,实现平台的独立性,事件传递过程如下:
RenderWidgetHostViewAura::InsertChar() -> RenderWidgetHostImpl::ForwardEventToRender()-> InputRouterImpl::offerToRender----->IPC-----> RenderWidget::OnReceiveMessage()-> WebWidget::Frame()->executeCommand()->frame::executeCommand()->Editor::executingCommand() 函数名不准确,后面改正;
4. TextInputClient的focus与detach,在页面或者UI输入框回去焦点的时候,TextInputClient 会被设置到IME中,但是当焦点改变的时候,IME中的TextInputClient并不会别清除,只有当当前windowDestroy或者说当前的window被removedFromRootView中时,IME才会将TextInputClient置为NULL,此处由于之前没有理解,也进了坑,使用InputMethod::GetTextInputClient()并不能准确的判断当前是否处于输入状态,以上就是主要原因,若要判断当前的输入状态可以使用InputMethod::GetTextInputType(),返回TEXT_INPUT_TYPE_NONE则处于非输入状态,返回其他值则处于输入状态;
5. 有时页面的输入框并不是一个输入框类型的元素,而是简单的div,此时使用InputMethod::GetTextInputClient()能够返回一个有效值,但是却不能使用InsertChar()去输入,此时的输入基本都是通过页面的js捕捉事件去完成,对于browser来说并不是真正的输入状态,而使用InputMethod::GetTextInputType()可以过滤这个情况。

后面将补全代码,目前仅仅是做一个记录。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: