miau's blog?

StaccatoEditor 技術まわりの課題

忘れないうちに書いておきます。なにか解決策とかご存じな方は教えてください。
ちなみに ActivePython 2.5.1.1+wxPython 2.8 って環境で開発してます。OS は WinXP だったり Vista だったり。




■スキャンコードが拾えない?

開発してる Windows マシンだとGetRawKeyFlags() でスキャンコード相当のものが拾えたんだけど、Linux で試したところ全然拾えていなかった。(どのキーを押しても 0 しかか返ってこなかった。)
あと、公開前に他の人に試してもらったりもしたんだけど、その人の Windows マシンでも上記の Linux と同じような症状になっていたから、やっぱりこのコードがうまく拾えてないんだと思う。(前項に書いたけど、USB キーボードなのがまずいのかも。)

物好きしか使わなそうなエディタだから利用環境は多いほうが嬉しいんだけど、この辺りどうしよう。たぶんスキャンコードを拾う方法は各 OS にちゃんとあるわけで、wxPython(というか wxWidget)が将来的にそれを吸収してくれるならいいんだけど、そうでないなら別のライブラリを検討したほうがいいかもしれない。

スキャンコード以外での判別も一応できるんだけど、その場合キー配列(英語だとか日本語だとか)を考慮する必要があるので汎用性がなくなってしまう。(各環境ごとの設定ファイルとか準備しないといけなくなる。)あと、その方法だと後述のように IME ON の状態でキーコードが拾えない。

■IME ON の状態でキーコードが拾えない

Linux でスキャンコードが拾えないことがわかってから、キーコードのほうで色々判定しようとしたんだけど、この方法にも問題が。
普通のキーであれば、KeyDown→Char→KeyUp みたいなイベントが発生するんだけど、IME が ON の状態だと、

(1) 「あ」を押す→離す
・KeyDown(Key Code: 229)
・KeyUp(Key Code: 65 = "A")
(2) 「い」を押す→離す
・KeyDown(Key Code: 229)
・KeyUp(Key Code: 73 = "I")
(3) Enter を押す→離す
・KeyDown(Key Code: 229)
・Char(Key Code: 12354 = "あ")
・Char(Key Code: 12354 = "い")
・KeyUp(KeyCode: 13 = WXK_RETURN)

みたいな感じでイベントが発生するみたい。KeyDown 時にそのコードがわからないと Staccato は実現できないから、この実装もやめ。とりあえず最初に作ってたのでスキャンコードを使う方法を継続して使っている。

■IME の制御がうまく行えない?

上記のように IME ON 時のキーイベントは拾えても、IME で押下したキーの情報を握っているのは変わらないから、それをエディタから制御してやる必要がある。エディタから IME に「それは modifier key だから文字入力しちゃダメだよ」みたいな情報を送ってやるイメージ。

第4回 クリップボード その1
関数 - Input Method Editor (IME) - プラットフォーム SDK

上の例にあるように WM_IME_COMPOSITION メッセージをうまくハンドルして、IME 関連の API を適切に呼んでやれば制御できるのかもしれないけど、ぱっと見た感じ wxPython で(Windows の)ウィンドウメッセージは制御できない感じ。

前項の末尾にも簡単に書いたけど、個人的にはこれが一番の問題。前 2 つの問題は環境依存としてあきらめるとしても、IME ON の状態で Staccato できないのはちょっと致命的。もっと低レベルな場所で実装(高いところだと API hook、低いとこだとデバイスドライバとか)でごにょごにょすればどうにでもなるんだろうけど、移植性低くなるからできればライブラリレベルで解決したいところ。

まずはネイティブアプリケーションでやりたいことが実現できるか調べて、できるようならそれに適合したライブラリ探しでもやろうかと。できないようなら・・・またそのとき考えます。

■wx.aui.AuiNotebook のキーイベント+フォーカス周りがうまくいかない

# この辺りは優先順位低いんだけど、一応書いておきます。
タブの制御は wx.aui.AuiNotebook ってコントロールに任せてます。なのでタブ機能がやたら充実してて、ドラッグ&ドロップでタブを入れ替えたり上下に分割したりは勝手にやってくれて便利なんだけど。

このコントロール、各タブをアクティブにする(タブの見出しにフォーカスがある状態にする)ことはできても、その子要素をアクティブにすることができないみたい。StaccatoEditor では各タブにエディタのメイン UI を張り付けてるんだけど、そこがアクティブになってくれないから、これだとタブ切り替え時にキー入力が利かなくなってしまう。今は WINAPI で強引にタブを移動させてるけど、もっとスマートな方法がないと移植のときに困る。

あと、開発当初このコントロールの子孫で発生したイベントを上に投げてくれなくてちょっと困ったりした。当初の設計ではキーイベントは各タブじゃなくてアプリケーションで一元管理するつもりだったので。結果的には各タブで制御する今の造りがよかったんだけど、期待通りに動いてくれないのは困る。

■DrawText をまとめて出力できない?

ここはパフォーマンスに絡む部分。
今はエディタの動作がやたら重いですが、特に重いのが文字出力の API 呼び出し部分です。なので、この API の呼び出し回数をなるべく減らしたいんだけど、まず簡単な方法として「複数の文字をまとめて出力」ってのが思いつくわけです。で、実際やってみると、文字の出力位置が予定とずれる。等幅フォントを使って「abc」とまとめて出力しても、それぞれの文字幅が均一になってくれない、というような状況。
仕方ないので今は「a」と出力した場合の文字幅取得→その横幅で等間隔に「a」「b」「c」と 3 回出力、みたいな面倒くさいことやってます。均一に出力する方法があったら教えてください・・・。


その他プログラム面でのメモとか感想とかも書こうと思ったけど、長くなりそうなのでまた明日にでも・・・。
posted at 03:00:30 on 2008-05-21 by miau - Category: TextEditor No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

No comments yet

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。