Sigil – カーソルが消える事象の解析

Sigilを使って直接原稿の作成作業を行った場合、日本語の変換等でCaretが消えてしまう現象が発生します。

とりあえずの回避コードを書いてみたものの、対応が正しいかどうか確証も持てず、もやもやしたので ちょっとだけ時間を使って調べてみました。

Windows+Sigil+MS IMEで発生する問題について以下に整理します。

  1. IMEで平仮名入力中に変換して漢字変換中にCaretが消え、その後消えたままになる事がある。その後変換前の平仮名を入力する事で復帰する。
  2. 連文節変換で分節確定をすると、その後の文節が表示されない。

1 について調べがつきました。2側については現状調べきれていません*1

原因はQtのQWebPage*2内、InputMethodEventの実装にあります。

IMEでの入力変換中、InputMethodEvent::Cursorがカーソル幅0で送られてくる事があり、このときにQWebPage内でCaretを消してしまっています。

その後Caretが復帰できるイベント、具体的にはCursorのLength>0のInputMethodEventが来るかFocusを失って再度Focusを得るまでCaretが復帰しません。

対応方法は以下の二通り

  • QtにPatchをあて、InputMethodEvent内にCaretの表示を復帰させるコードを入れる
  • Sigil側にCaretの表示を復帰させるコードを入れる

前者のQtにPatchを当てるのが本筋ですが、既にQtはVersion 5.0が最新でQt4にPatchを適用するよりはQt5へ変更し そこにPatchを考えた方が良いように思います。

とりあえず今回は簡単に対応したいこともあって 後者のSigil側の修正を考えてみました。

InputMethodEventはBookViewEditorでOverride可能で、このEventをHookする事ができます。WebKitのWebCore::Frameが取得できれば適当なタイミングでsetCaretVisible(true);を発行する事でCaretを復帰させる事は可能と思われます。

ただ、QtのFrameworkの中からWebCore::Frameが取得する方法が無く直接Caretを復帰させるコードを書く事はできないようです。

正攻法がダメなので、副作用としてCaretの表示制御をしているコードを呼び出してやる事で対応をする事ができました。

これでCaretが消える事はなくなるので、連文節変換をしなければ一般的な編集作業上の大きな問題はクリアできそうです。

Patchについては、Qt5対応とあわせて実現できてからFeedback、公開*3しようと考えていますが、もしも現対応のPatchをご希望の方がいたらコメントに何か残していただければとおもいます。


*1 自分は細切れに、ほぼ単文節で変換をするので若干ヤル気は低いです(^_^;)、、、。

*2 Qt5ではQWebPageAdaptor内

*3 Work Around Codeって開発側に送ってもRejectされる事あるんですよね。本質的にQtが悪いわけで、Qtを修正するのが筋。Sigil側で治すべきではありませんから。