Pharo で日本語の文章をインライン入力しても入力中は何も表示されない。Enter で確定するとなぜか最初の1文字だけが入力される。(たとえば、「あいうえお」+Enter と入力すると「あ」だけ表示される)
インライン入力に対応していないのは諦めるとしても、1文字しか入力されないのはとても不便である。
これは、OSWindowMorphicEventHandler>>#visitTextInputEvent: で、OSから受け取ったテキストの先頭文字しかキーイベントを生成していないせいだった。(下記太字部分)
visitTextInputEvent: anEvent
| keyEvent char mods |
anEvent text ifNil: [ ^ nil ].
char := anEvent text first.
char ifNil: [ ^ nil ].
mods := anEvent modifiers.
"If a modifier key is pressed the keystroke event is handled by #visitMouseDownEvent:"
(mods alt or: [ mods ctrl or: [ mods cmd ] ])
ifTrue: [ ^ nil ].
keyEvent := KeyboardEvent new
setType: #keystroke
buttons: (self convertModifiers: anEvent modifiers)
position: (self convertPosition: anEvent position)
keyValue: char charCode
charCode: char charCode
hand: self activeHand
stamp: Time millisecondClockValue.
^ keyEvent
anEvent text には、ちゃんと入力テキストが入ってくるんだけど、first で先頭文字だけを KeyboardEvent にしているのが原因。
はて、これをどう修正したものか。
このメソッドに渡されるイベントは、 OSTextInputEvent オブジェクトで、このオブジェクトを生成しているのは OSSDL2BackendWindow>>#visitTextInputEvent: だけだった。
visitTextInputEvent: event
| osEvent |
osEvent := OSTextInputEvent for: osWindow.
osEvent text: (ZnUTF8Encoder new decodeBytes: event text);
position: self mousePosition.
^ osEvent deliver
詳しく調べていないのでよくわからないが、osEvent deliver で生成したイベントを引き渡しているようだったので、文字ごとに分解して文字列分だけ送るように直してみた。
visitTextInputEvent: event
| osEvent text last |
text := ZnUTF8Encoder new decodeBytes: event text.
text do: [ :each |
last := each.
osEvent := OSTextInputEvent for: osWindow.
osEvent
text: each asString;
position: self mousePosition.
osEvent deliver ].
^ last
とりあえず確定文字列が全て入力されるようになった。他に悪影響が出るのかどうかはわからない。