Posting Keyboard Events
-
Hi everyone,
I'm having a heck of a time figuring out how to post keyboard events.
I've been working on this for a couple hours, googling everything I
can think of, but I'm still stuck.
First off, I'm aware of the functions:
CGPostKeyboardEvent()
CGEventCreateKeyboardEvent()
CGEventPost()
I've tried every combination of those that I can think of. For
modifier keys, it "seems" to work, but when it comes to actual letter
keys, it craps out on me. For example, if I try to do:
CGPostKeyboardEvent((CGCharCode)0, (CGKeyCode)56, true);
CGPostKeyboardEvent((CGCharCode)0, (CGKeyCode)6, true);
CGPostKeyboardEvent((CGCharCode)0, (CGKeyCode)6, false);
CGPostKeyboardEvent((CGCharCode)0, (CGKeyCode)56, false);
I'm expecting a capital "A" to get typed. All I get is a system beep
once I try to type the A. (Line 2)
So I tried a different way:
CGEventRef shiftDown = CGEventCreateKeyboardEvent(NULL,
(CGKeyCode)56, true);
CGEventRef shiftUp = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)56,
false);
CGEventRef aDown = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)6,
true);
CGEventRef aUp = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)6, false);
CGEventPost(kCGHIDEventTap, shiftDown);
CGEventPost(kCGHIDEventTap, aDown);
CGEventPost(kCGHIDEventTap, aUp);
CGEventPost(kCGHIDEventTap, shiftUp);
Again the beep.
Then I found a reference to needing this beforehand:
CFRelease(CGEventCreate(NULL));
Guess what! I still get the beep.
SKIMMERS START READING HERE:
How on earth can I post system keyboard events (without getting a beep)?
Thanks a bunch!
Dave DeLong
ps - Mac OS X 10.5.4, Xcode 3.1, Mac Mini Core Duo -
On Sep 5, 2008, at 9:15 PM, Dave DeLong wrote:> How on earth can I post system keyboard events (without getting a
> beep)?
You know, there are plenty of occasions when typing a letter causes a
beep. In particular, if there's no responder which is ready to accept
keyboard input. Is there a text view with focus at the time you're
posting the event?
Cheers,
Ken -
Yes, thank you for asking.
This code is in an IBOutlet for a simple controller object. The
controller has an outlet for the window and a textfield. The first
thing fun on this outlet is the following:
[window makeFirstResponder:textField];
And that does work, because the NSTextField is getting the focus and
blinking cursor, etc.
Dave
On 5 Sep, 2008, at 8:56 PM, Ken Thomases wrote:> On Sep 5, 2008, at 9:15 PM, Dave DeLong wrote:
>
>> How on earth can I post system keyboard events (without getting a
>> beep)?
>
> You know, there are plenty of occasions when typing a letter causes
> a beep. In particular, if there's no responder which is ready to
> accept keyboard input. Is there a text view with focus at the time
> you're posting the event?
>
> Cheers,
> Ken
> -
At 20:15 -0600 5/9/08, Dave DeLong wrote:> How on earth can I post system keyboard events (without getting a beep)?
As Ken mentioned, first off make sure the key has somewhere to go.
After that, this is roughly the code I use in Keyboard Maestro
(extracted bits and pieces, so it wont compile directly). My
apologies for the appearance of the code in email, but perhaps it is
still useful.
verify_noerr( ::CGEnableEventStateCombining( false ) );
verify_noerr( ::CGSetLocalEventsFilterDuringSuppressionState(
kCGEventFilterMaskPermitAllEvents,
kCGEventSupressionStateSupressionInterval ) );
verify_noerr( ::CGSetLocalEventsSuppressionInterval( 0.0 ) );
PostModifierKeys( inModifiers, true );
verify_noerr( CGPostKeyboardEvent( inChar, inKeyCode, true ) );
verify_noerr( CGPostKeyboardEvent( inChar, inKeyCode, false ) );
PostModifierKeys( inModifiers, false );
verify_noerr( ::CGEnableEventStateCombining( true ) );
with:
void
UCGRemoteControl::PostModifierKeys( const UInt32& inModifiers,
Boolean inKeyDown )
{
if ( inModifiers&( UInt32(shiftKey) ) ) {
verify_noerr( ::CGPostKeyboardEvent( (CGCharCode)0,
kCGShiftKeyCode, inKeyDown ) );
}
if ( inModifiers&( UInt32(controlKey) ) ) {
verify_noerr( ::CGPostKeyboardEvent( (CGCharCode)0,
kCGControlKeyCode, inKeyDown ) );
}
if ( inModifiers&( UInt32(optionKey)) ) {
verify_noerr( ::CGPostKeyboardEvent( (CGCharCode)0,
kCGOptionKeyCode, inKeyDown ) );
}
if ( inModifiers&( UInt32(cmdKey) ) ) {
verify_noerr( ::CGPostKeyboardEvent( (CGCharCode)0,
kCGCommandKeyCode, inKeyDown ) );
}
}
There is an extra piece of code to release the desired key if it is
already down (if the user is pressing the A key already, and you try
to press it again without first releasing it, it wont work).
Also, the key code for A is 0. 6 is Z.
Further, inChar should be lowercase (ie 'a' or 'z').
Enjoy,
Peter.
--
Keyboard Maestro 3 Now Available!
Now With Status Menu triggers!
Keyboard Maestro <http://www.keyboardmaestro.com/> Macros for your Mac
<> <<A href="http://download.stairways.com/">http://download.stairways.com/> -
Le 6 sept. 08 à 14:00, Peter N Lewis a écrit :> At 20:15 -0600 5/9/08, Dave DeLong wrote:
>> How on earth can I post system keyboard events (without getting a
>> beep)?
>
> As Ken mentioned, first off make sure the key has somewhere to go.
>
> After that, this is roughly the code I use in Keyboard Maestro
> (extracted bits and pieces, so it wont compile directly). My
> apologies for the appearance of the code in email, but perhaps it is
> still useful.
>
>
> verify_noerr( ::CGEnableEventStateCombining( false ) );
>
> verify_noerr
> ( ::CGSetLocalEventsFilterDuringSuppressionState
> ( kCGEventFilterMaskPermitAllEvents,
> kCGEventSupressionStateSupressionInterval ) );
> verify_noerr( ::CGSetLocalEventsSuppressionInterval( 0.0 ) );
>
> PostModifierKeys( inModifiers, true );
> verify_noerr( CGPostKeyboardEvent( inChar, inKeyCode, true ) );
> verify_noerr( CGPostKeyboardEvent( inChar, inKeyCode, false ) );
> PostModifierKeys( inModifiers, false );
>
> verify_noerr( ::CGEnableEventStateCombining( true ) );
>
>
> with:
>
>
> void
> UCGRemoteControl::PostModifierKeys( const UInt32& inModifiers,
> Boolean inKeyDown )
> {
> if ( inModifiers&( UInt32(shiftKey) ) ) {
> verify_noerr( ::CGPostKeyboardEvent( (CGCharCode)0,
> kCGShiftKeyCode, inKeyDown ) );
> }
>
> if ( inModifiers&( UInt32(controlKey) ) ) {
> verify_noerr( ::CGPostKeyboardEvent( (CGCharCode)0,
> kCGControlKeyCode, inKeyDown ) );
> }
> if ( inModifiers&( UInt32(optionKey)) ) {
> verify_noerr( ::CGPostKeyboardEvent( (CGCharCode)0,
> kCGOptionKeyCode, inKeyDown ) );
> }
> if ( inModifiers&( UInt32(cmdKey) ) ) {
> verify_noerr( ::CGPostKeyboardEvent( (CGCharCode)0,
> kCGCommandKeyCode, inKeyDown ) );
> }
> }
>
> There is an extra piece of code to release the desired key if it is
> already down (if the user is pressing the A key already, and you try
> to press it again without first releasing it, it wont work).
>
> Also, the key code for A is 0. 6 is Z.
It's true on QWERTY keyboard, but you should not rely on this. -
Not sure if this got through... I was getting "Your message is
awaiting moderation messages" even though I'm signed up for the list.
Dave
On 5 Sep, 2008, at 9:51 PM, Dave DeLong wrote:> Yes, thank you for asking.
>
> This code is in an IBOutlet for a simple controller object. The
> controller has an outlet for the window and a textfield. The first
> thing fun on this outlet is the following:
> [window makeFirstResponder:textField];
>
> And that does work, because the NSTextField is getting the focus and
> blinking cursor, etc.
>
> Dave
>
> On 5 Sep, 2008, at 8:56 PM, Ken Thomases wrote:
>
>> On Sep 5, 2008, at 9:15 PM, Dave DeLong wrote:
>>
>>> How on earth can I post system keyboard events (without getting a
>>> beep)?
>>
>> You know, there are plenty of occasions when typing a letter causes
>> a beep. In particular, if there's no responder which is ready to
>> accept keyboard input. Is there a text view with focus at the time
>> you're posting the event?
>>
>> Cheers,
>> Ken


