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