on-the-spotモードにおけるXmbResetIC()の挙動変更

背景

on-the-spot対応日本語XIMサーバ 機能と実装の比較で書いたように、VJE-Delta 3.0では、クライアントがXmbResetIC()を呼び出しても、XIMサーバ(vje)は自分側の前編集文字列を消去しないどころか、前編集文字列を(一部だけ)再描画しようとしてクライアントの描画コールバックを呼び出すという仕様になっています。このような実装では、editorは正常に動作しません。

一般にXIMを利用するアプリケーションでは、クライアントがひとつのIMをオープンして、ICを1つだけ生成するケースと、ICを複数生成するケースが考えられます。前者のケースでは、そのクライアントのもつ複数のテキスト入力オブジェクトで唯一のICを使い回し、クライアントの最下行の状態表示領域を共有するという実装になります。オブジェクト間でキーボードフォーカスが移動するときに、コールバック関数のポインタ一式を変更するため、前編集文字列が存在すればXmbResetIC()でそれをリセットする必要があります。XIMプロトコルではクライアントがXIMサーバに対して明示的に前編集文字列を操作できないということが、その根本的原因です。

後者のケースでは、それぞれのテキスト入力オブジェクトごとにICを生成するので、そのような問題は起きません(リセットの必要がありません)。しかし、オブジェクトが個別に状態表示領域を用意する必要があります(共有できないため)。打開策として、XIMスタイルにXIMStatusNoneを使用する手もあるでしょう。

両方のケースに対応するためには、結局XmbResetIC()を使用する必要があるため、この仕様はそれぞれのXIMサーバで一致していて欲しいものです。

処置

XmbResetIC()の仕様が明確でないから別にvjeが悪いわけではないのですが、例のごとくvjeはソースが提供されるので、パッチを作ってみました。パッチの当て方は、次の通りです。

% tar zxvf delta.tgz
% cd delta
% gzip -dc どこか/vje-3.0-xmb_reset_ic.patch-1.gz | patch

このパッチを適用したvjeは、XmbResetIC()を呼び出すと、XIMサーバ側の前編集文字列をすべてキャンセルしてから、描画コールバックを呼び出してクライアント側の前編集文字列を消去するような動作になります。