AquaSKK 4.2 RC3

リリースしました。

▽追加・改善された機能
・特になし

▽不具合修正
・かな規則がすぐに反映されない

かな規則の不具合は再ログインすれば反映される、というお話から、ひょっとしてキャッシュが効いてしまっているのかなと思い、対策してみました。こちらでは再現しないので、確認してもらえると助かります。

Eclipse で更新状態になってしまう件については改善されていません。現状わかっていること(推測もありますが)を書いておきます。

そもそもの問題点

Mac OS X におけるキー入力は通常、システム → IME(AquaSKK など) → アプリケーションの順番で伝播します。例えば、「a」というキー入力が発生すると、AquaSKK はそれをアプリケーション(の proxy オブジェクト)に対して渡します(insertText)。するとアプリケーション側のメソッドが呼ばれて、実際に「a」を描画するという流れになるわけです。

ほとんどのケースはこれで OK なのですが、AquaSKK で言うところの文字種の切り替えキーなどは、そのまま描画されると困ってしまいます。そこで、システムに対して「IME で処理済みだよ」と伝えることで、描画は発生しないけれども、システムはアプリケーションへのイベント伝播をやめる仕組みとなっています。

Eclipse (というか、JRE)における問題は、この「IME で処理済みだよ」を無視してしまう点にあります。

結果として、文字種切り替えキーがそのまま描画されてしまうわけです。ヒドイヨヒドイヨ!!!

なぜ無視してしまうのか?

お行儀の良いアプリケーションではそもそもこういった問題は発生しません。なぜなら、システムがキー入力を渡すことはないからです。では、なぜ Eclipse ではこうなってしまうのか。

それは、キー入力イベントで様々な処理を行いたいからに尽きると思います。ここは推測になりますが、おそらく Eclipse(というか、JRE)ではキー入力を横取りして、以下のような流れになっていると思われます。

システム → JRE(アプリケーション) ⇄ IME

ハリウッドの原則が意図的に無視され、IME は単なるサブルーチンとなっています。同じような実装をしているのが、iTerm などターミナルアプリケーションです。つまり、キー入力に重点を置くアプリケーションはどうしても、こういったモデルにならざるを得ないという事情があるかと思います。

どうすればいいのか?

根本的には Mac OS X 版の JRE を修正し、IME 呼び出し後に「処理済みだよ」と言われたら、アプリケーションにキーを渡さないようにすればいいと思われます。現在の実装ではこの返事を無視し、IME がキー入力を消費だけして出力しない場合には、すなわち処理されなかったイベントと判断して、アプリケーションに横流ししている節があります。

以前、Safari の HTML フォームでも同様の問題が発生したことがあったのですが、その時は不具合報告して対応してもらった経緯があります。JRE はどうすればいいのかなぁ。

ちなみに、ことえりGoogle IME でも文字種切り替え時には Eclipse にゴミが挿入されるケースがあります。

AquaSKK の苦肉の策

というわけでかなり困難な状況なわけですが、要は、IME がなにかしら出力すればアプリケーションにキーが渡ることはないわけです。この秘孔を突いて、AquaSKK では未確定文字列を挿入することで、アプリケーションへのキー伝播をキャンセルするという荒技を行っています。

確定文字列では実際に描画されてしまうので、未確定文字列にするところがこの技の最大のポイントです。最初は null を挿入していたのですが、Eclipse で効果がなかったため、Ctrl-L を挿入するようにしたところ、おとなしくなってくれたのはご存知の通りです。

これでアプリケーション上はゴミが挿入されることがなくなったのですが、その副作用として、ファイルが編集状態になってしまう、という事態を引き起こしてしまったわけですね。おぞましいですが、これは現状、いかんともしがたいなぁと。

まとめ

Java なんか捨てちまえ!!! 嘘です。