views:

54

answers:

1

I'm trying to use event taps to create an OS X program that will listen for Yiddish typed in transliteration and post the result in Hebrew characters. I made a very short program to test one things I'd have to do: http://pastie.org/791398

As is, the program successfully replaces every typed 'q' with 'w':

if(inputString[0] == 'q') { inputString[0] = 'w'; }

But how does one post a string of more than one character? For instance, if someone types 'sh' you'd presumably have to post a backspace (to delete the character that was posted for 's' alone) and then post the character that corresponds to 'sh'. However, this code results in only a backspace being posted:

else if(inputString[0] == 'm') { inputString[0] = '\b'; inputString[1] = 'n'; }

I apologize if these are basic questions; I have read all the documentation I could find, but I might not have understood it all. It's also possible that I'm going about this entirely the wrong way.

A: 

Ideally you should be using an input method instead of a program with event taps, most likely using Input Method Kit if you don't need to support pre-10.5. Using event taps for this purpose is inherently a bad idea because the user can change where he/she is typing with the mouse as well as the keyboard. So if the user typed a "s" in one text field followed by a "h" in another, you wouldn't be able to tell the difference.

That said, here's a direct answer to your question.

The string is length-counted, so you can't just provide the incoming length (1); the second character will be ignored. However, most applications also don't like to get more than a single character per event, so they'll just discard the remaining characters. (Terminal is a notable exception.)

So what you can do is simply post a second event with the second character in it.

else if(inputString[0] == 'm') {
  inputString[0] = 'n';
  CGEventKeyboardSetUnicodeString(event, 1, inputString);
  CGEventPost(kCGSessionEventTap, event);
  inputString[0] = '\b';
}

In the general case (simulating > 2 keypresses) you'll need to create an event for each character you want to insert. This mailing list post includes a simple example.

Nicholas Riley
Thanks! That's really useful to know -- and you're right that I should have been making an input method with IMKit. (Actually, it turns out to be easier to use an input method framework like MacUIM: http://code.google.com/p/macuim/)
Raghav