先月、CocoaInputLinuxをリリースしましたが、それについて少し設計を書きます。
以前私はgistに「lwjgl2コード内の”@im=none”を消せば日本語が打てる」と書きましたが、それだけでは不十分でした。
X11でIMを使用するにはキーイベントをXIM(filterEvent)に渡す必要があります。これは大前提事項で、コレがなされていないとMod側の対処ではどうにもなりません。Modだけでどうにもならないということはライブラリに改変を施す必要があるわけです。
https://github.com/LWJGL/lwjgl/blob/master/src/java/org/lwjgl/opengl/LinuxDisplay.javaのコード
863: if (event_window != getWindow() || event_buffer.filterEvent(event_window) ||…
一見するとXIMにキーイベントを渡しているように見えますが、実はXIMの向けのキーイベントの時はevent_window != getWindow()がfalseを返してしまうようです。よって本来のXIMにキーイベントを渡す実装は
if (event_buffer.filterEvent(event_window)||event_window != getWindow()…
とするべきでした。
それでこれらの対策方法についてですがめんどくさいので省略します。
結果的にCocoaInputLinuxをインストールする時に置き換えられるlwjglのライブラリの変更点は以下の通り。
LinuxEventクラスについて、
メンバを追加
private boolean finalEventFiltered = false;
public static boolean enableIME = false;
メソッドを改変
public boolean filterEvent(long paramLong){
return this.finalEventFiltered;
}
public boolean filterEventX(long paramLong){
return enableIME ? nFilterEvent(this.event_buffer, paramLong) : false;
}
public void nextEvent(long paramLong){
nNextEvent(paramLong, this.event_buffer);
this.finalEventFiltered = filterEventX(0L);
}
この改変が全てです。こういうのをちゃんと書いておかないとキーロガーしてるんじゃないかと思われそうなので書いておきます。
なおMinecraft 1.13から採用されるlwjgl3はしっかりとfilterEventを通しているようなので、恐らくCocoaInputLinuxをmodsディレクトリに入れるだけで動くと思います。
現状のCocoaInputLinuxははっきり言ってIMEを表示させた段階で終わっていて利便性が高いとはいえません。
何より情報が非常に少なく、変換候補のウィンドウの表示位置の制御がにっちもさっちもいきません。
こればっかりは対策するのには時間がかかるor直せないということになりそうです。