日本語入力開発者の集い

昨日、MacUIM の谷津さんに誘われて、飲み会に参加してきました。キートップがたくさん並んだ不思議なドラムセットのある会社の食堂という、今までにないシチュエーションでしたが、刺激的なお話をたくさん伺えて楽しかったです。こちらからは提供するネタがなくて申し訳ありませんでした。

その場で InputMethodKit に関する質問があって、アプリケーションから入力モードを変更するにはどうすればいいのか、と聞かれました。どのレイヤーの話か特定できなかったのと、あらかた忘れていて答えられなかったので、こちらで埋め合わせをしておきます。

IMKTextInput プロトコル

TextEdit 等のアプリケーションが起動すると、InputMethodKit は 対向の入力セッションとして IMKInputController を生成します。

- (id)initWithServer:(IMKServer*)server delegate:(id)delegate client:(id)inputClient

引数として渡される inputClient が、TextEdit 等のアプリケーションプロキシです。このオブジェクトは IMKTextInput プロトコルを実装しているため、以下のメソッドを呼び出すことで入力モードを変更することができます。

-(void)selectInputMode:(NSString*)modeIdentifier

modeIdentifier に指定するのは "com.apple.inputmethod.Japanese.Hiragana" のような文字列です。これは、Info.plist の ComponentInputModeDict に記述した入力モードのどれかと一致している必要があります。

入力メニューアイコンとの関係

右上の入力メニューには通常、入力モードに応じたアイコンが表示されます。IMKTextInput の selectInputMode で入力モードを変更すると、InputMethodKit によってアイコンも自動的に変更されます。

ところで、入力メニューから入力モードを変更するとどうなるのでしょうか。この場合には、IMKStateSetting プロトコルの以下のメソッドが呼ばれます。

- (void)setValue:(id)value forTag:(long)tag client:(id)sender

大抵、IMKInputController は IMKStateSetting も実装することになるので、各入力セッションがこのイベントを処理することになります。引数の tag が kTextServiceInputModePropertyTag の時、value には "com.apple.inputmethod.Japanese.Hiragana" 等の modeIdentifier が渡されてきます。これを判別して、内部の入力モードを変更するわけです。なお、setValue はアクティブなアプリケーションが切り替わった時にも呼び出されます。

入力モード保持オプションの廃止とその対処

Leopard になって、文書毎に入力モードを保持するオプションが廃止されるという事件がありました。甚だ迷惑な仕様変更ですが、とにかく入力メソッドで類似の機能を実装しなければということで、AquaSKK では統合モードという特別な入力モードを用意しました。

統合モードを使うと、入力モードを切り替えてもアイコンは常に同じままです。こうすることで、アプリケーション切り替え時の暗黙的な setValue による入力モードの上書きを防ぐことができます。つまり、modeIdentifier と入力メソッドの内部入力モードをあえて分離しておくわけです。

入力モード保持オプションは Snow Leopard になってめでたく復活したので、入力モードとアイコンが一対一で対応するモードも再び実用的になりました。

まとめ

入力メソッドまわりは謎な仕様や、トラップの類いがとても多い気がします。歴史的な経緯とか、捨てられない互換性とか、理由はいくつか考えられますけど、フレームワークを提供する側の人的リソース不足も結構大きい気がします。そしてそれは、フレームワークを利用する開発者側にもあてはまるんですよね。だから声が届きにくい。結果、細部の作り込みが不十分だったり、情報が不足したフレームワークに四苦八苦するという悪循環。あっちもこっちもどっちも大変。開発者がつながりを求めるのも自然な話ですね。

AquaSKK のメンテナになってからのあれやこれやを思い出し、久々に感慨深い夜でした。