FROM : Douglas Davidson
DATE : Tue Apr 05 18:15:22 2005
On Apr 4, 2005, at 6:01 PM, Daniel Child wrote:
> I have been trying to understand how input method editors work in
> Cocoa. If you type Japanese, a long bar comes out, but the type of ?
> view? ?window? seems unlike those provided in Interface Builder. A
> line of characters are typed out, or listed in a box.
>
> Also, I am wondering what kind of keyboard interception is taking
> place so that when you type roman letters it gets converted into
> other things like kana and kanji.
>
> If anyone could point to relevant documentation or on the most
> important classes to understand, please let me know. I've looked
> around but haven't come up with much.
>
There are several ways to approach this, depending on whether you are
thinking of writing a view that accepts keyboard input, or writing an
input method, or just trying to understand how the whole thing
works. When a key is pressed, a key-down NSEvent is generated, and
NSApplication passes it to the key window, which passes it to the
first responder by calling its keyDown: method. For a text-handling
view like NSTextView, the keyDown: method will then call [self
interpretKeyEvents:] (an NSResponder method) which will start the
interpretation and key binding process.
Now, in most cases the key events will come back to the view either
as insertText: (for ordinary key presses with an ordinary keyboard)
or as doCommandBySelector: (for special keys like delete, return,
etc.), as the NSResponder.h comments mention. However, if a special
input method like Kotoeri is active, then something else will
happen. To handle those cases, NSTextView conforms to the
NSTextInput protocol. In those cases, unconfirmed text (called
"marked" text) will be sent to the text view via the
setMarkedText:selectedRange: method. NSTextView then usually
displays the marked text with an underline. The remaining methods in
NSTextInput are primarily to allow the input method to query the text
view for information that it needs to display its apparatus.
The input method itself is a kind of plugin--for example, Kotoeri is /
System/Library/Components/Kotoeri.component. The TSM documentation
will help you understand how these components are written, and how
they manage their communication with the rest of the app using TSM.
As a plugin running in the application, the input method can put up
panels or other UI apparatus as needed.
If you are writing a text-oriented view and you want to be able to
receive input from input methods, then primarily what you need to do
is to pass your key events to interpretKeyEvents:, and to conform to
the NSTextInput protocol.
If you are just working with NSTextView, then you should be generally
aware of this process. For example, I have repeatedly recommended
that in most cases it is not a good idea to subclass NSTextView and
override keyDown:. That is because handling key events in this
manner will bypass all of the key binding and input method
processing. If you were to handle returns, for example, in keyDown:,
then an input method that gave a special meaning to return would
probably be broken in your app. If possible, it is better to work at
a higher level, with the insertText: or doCommandBySelector: calls
that key presses eventually generate, or better yet to handle the
resulting delegate methods like textView:doCommandBySelector:,
textView:shouldChangeTextInRange:replacementString:, or
textView:willChangeSelectionFromCharacterRange:toCharacterRange.
You should also be aware that in some cases the text view will
contain and display text that is only tentative, not yet confirmed by
the user. You can find out whether this is the case by calling -
hasMarkedText, and you can determine where it is using -markedRange.
Another thing to keep in mind is that the NSTextInput methods are
really intended only for dealing with input methods. In some cases I
have seen developers try to use NSTextInput methods like -
firstRectForCharacterRange: or -characterIndexForPoint: in other
contexts. These really are not intended for general-purpose use;
they are specialized for the needs of input methods, and in most
cases if you are not dealing with input methods you should use
something else.
Douglas Davidson
DATE : Tue Apr 05 18:15:22 2005
On Apr 4, 2005, at 6:01 PM, Daniel Child wrote:
> I have been trying to understand how input method editors work in
> Cocoa. If you type Japanese, a long bar comes out, but the type of ?
> view? ?window? seems unlike those provided in Interface Builder. A
> line of characters are typed out, or listed in a box.
>
> Also, I am wondering what kind of keyboard interception is taking
> place so that when you type roman letters it gets converted into
> other things like kana and kanji.
>
> If anyone could point to relevant documentation or on the most
> important classes to understand, please let me know. I've looked
> around but haven't come up with much.
>
There are several ways to approach this, depending on whether you are
thinking of writing a view that accepts keyboard input, or writing an
input method, or just trying to understand how the whole thing
works. When a key is pressed, a key-down NSEvent is generated, and
NSApplication passes it to the key window, which passes it to the
first responder by calling its keyDown: method. For a text-handling
view like NSTextView, the keyDown: method will then call [self
interpretKeyEvents:] (an NSResponder method) which will start the
interpretation and key binding process.
Now, in most cases the key events will come back to the view either
as insertText: (for ordinary key presses with an ordinary keyboard)
or as doCommandBySelector: (for special keys like delete, return,
etc.), as the NSResponder.h comments mention. However, if a special
input method like Kotoeri is active, then something else will
happen. To handle those cases, NSTextView conforms to the
NSTextInput protocol. In those cases, unconfirmed text (called
"marked" text) will be sent to the text view via the
setMarkedText:selectedRange: method. NSTextView then usually
displays the marked text with an underline. The remaining methods in
NSTextInput are primarily to allow the input method to query the text
view for information that it needs to display its apparatus.
The input method itself is a kind of plugin--for example, Kotoeri is /
System/Library/Components/Kotoeri.component. The TSM documentation
will help you understand how these components are written, and how
they manage their communication with the rest of the app using TSM.
As a plugin running in the application, the input method can put up
panels or other UI apparatus as needed.
If you are writing a text-oriented view and you want to be able to
receive input from input methods, then primarily what you need to do
is to pass your key events to interpretKeyEvents:, and to conform to
the NSTextInput protocol.
If you are just working with NSTextView, then you should be generally
aware of this process. For example, I have repeatedly recommended
that in most cases it is not a good idea to subclass NSTextView and
override keyDown:. That is because handling key events in this
manner will bypass all of the key binding and input method
processing. If you were to handle returns, for example, in keyDown:,
then an input method that gave a special meaning to return would
probably be broken in your app. If possible, it is better to work at
a higher level, with the insertText: or doCommandBySelector: calls
that key presses eventually generate, or better yet to handle the
resulting delegate methods like textView:doCommandBySelector:,
textView:shouldChangeTextInRange:replacementString:, or
textView:willChangeSelectionFromCharacterRange:toCharacterRange.
You should also be aware that in some cases the text view will
contain and display text that is only tentative, not yet confirmed by
the user. You can find out whether this is the case by calling -
hasMarkedText, and you can determine where it is using -markedRange.
Another thing to keep in mind is that the NSTextInput methods are
really intended only for dealing with input methods. In some cases I
have seen developers try to use NSTextInput methods like -
firstRectForCharacterRange: or -characterIndexForPoint: in other
contexts. These really are not intended for general-purpose use;
they are specialized for the needs of input methods, and in most
cases if you are not dealing with input methods you should use
something else.
Douglas Davidson
| Related mails | Author | Date |
|---|---|---|
| Daniel Child | Apr 5, 03:01 | |
| Satoshi Matsumoto | Apr 5, 03:31 | |
| Daniel Child | Apr 5, 07:35 | |
| Douglas Davidson | Apr 5, 18:15 | |
| Daniel Child | Apr 5, 22:46 | |
| Satoshi Matsumoto | Apr 5, 22:56 | |
| Douglas Davidson | Apr 5, 23:01 | |
| Aki Inoue | Apr 5, 23:06 | |
| Aki Inoue | Apr 5, 23:08 |






Cocoa mail archive

