Bug-org 1200980 [e10s][TSF] Candidate window is sometimes not positioned properly because IMEContentObserver sometimes fails to notify IME of selection change
初回投稿日時: 2015-09-17 21:39:08
カテゴリ: e10s Events IME Mozilla Core Mozilla43 TSF Windows バグ修正
SNS:
Tweet (list)
twitter.comでリプライを入力する時にATOKのナビバーや、様々なTIPのサジェストウインドウや、候補ウインドウがキャレット位置等の適当な位置に表示されないというバグです。
調査してみると、ContentCacheInChildがNOTIFY_IME_OF_POSITION_CHANGEを受け取ってWidgetQueryContentEventを利用してコンテンツの情報を取得し、キャッシュする際に選択範囲がおかしな値になっていることがあることが分かりました。その原因は今でも分かっていませんが、NOTIFY_IME_OF_POSITION_CHANGEを通知してはいけないタイミングが未だに存在し、ContentEventHandlerがフォーカスを持ったcontenteditableなエディタだけではなく、ドキュメント全体をターゲットにしてコンテンツを取得して値がおかしくなっているようでした。
根本的な原因の調査にはものすごく時間がかかることが明らかなので、無理の無いアプローチでバグを隠してしまうことにしました。まず、WidgetQueryContentEventをContentEventHandlerに渡す場所を変更しました。エディタがフォーカスを持たない場合は今まで通りEventStateManager::PreHandleEvent()から処理しますが、IMEContentObserverのインスタンスが存在する場合はIMEContentObserver経由で呼び出すようにしました。
これにより、WidgetQueryContentEventの戻り値の値をキャッシュし、適切な時に破棄することが可能になります。今回の場合、選択範囲を正しく返すことができればひとまずバグを隠すことができるので、NS_QUERY_SELECTED_TEXTに対しては常にキャッシュしてある情報を返すようにしました。これにより、安全なタイミングでキャッシュされた正しい選択範囲の情報が常にTIPに渡るようになっています。
なお、このバグの調査のために書いたIMECntentObserverのロギングコードはそのまま投入されていますので、NSPR_LOG_MODULES=IMEContentObserver:5でIME (widget)への通知の発行部分をログから調査できるようになっています。
また、IMEContentObserver::EditAction()が適切に呼び出されないバグも発見したため、修正していますが、これの副作用により、inputイベントの発火仕様が若干変更されています。未確定文字列が空になった時にはinputイベントが発火されていませんでした。これは、未確定文字列になった時には直後にcompositionendが来て、その後にinputイベントが確実に発火されるという前提に基づいたものでしたが、compositionendを伴わないケースではinputイベントが発火するようになっています。この変更は実際にはどのIMEを利用していてもおそらく実際には発生しない差異だとは思います(知る限り、そのような動作をしたIMEを知らない)。