user635064
user635064

Reputation: 6247

CGEvent NSKeyDown only working if app is front most?

I am trying to automate some tasks (there's no applescript support) so I have to use CGEvents and post these events. Mouse clicking works fine, but NSKeyDown (enter) only works if I click on the app in the dock(which makes it front most app)... Here's my code so far:

   for (NSDictionary *dict in windowList) {
        NSLog(@"%@", dict);
        if ([[dict objectForKey:@"kCGWindowName"] isEqualToString:@"Some Window..."]) {
            WIDK = [[dict objectForKey:@"kCGWindowNumber"] intValue];
            break;
        };
    }


    CGEventRef CGEvent;
    NSEvent *customEvent;

    customEvent = [NSEvent keyEventWithType:NSKeyDown 
                                   location:NSZeroPoint 
                              modifierFlags:0 
                                  timestamp:1 
                               windowNumber:WIDK
                                    context:nil 
                                 characters:nil 
                charactersIgnoringModifiers:nil 
                                  isARepeat:NO 
                                    keyCode:36];

    CGEvent = [customEvent CGEvent];
    for (int i=0; i <5; i++) {
        sleep(3);
        CGEventPostToPSN(&psn, CGEvent);
        NSLog(@"posted the event");
    }

    CFRelease(eOne);

The reason why I have posteventtopsn in a loop is for testing purposes (I just need it to send it once). While the program is in the loop, if I activate my app to front most, then the event works fine.

What am I doing wrong? Is there a way it can work if it in background? Thanks.

Upvotes: 0

Views: 1834

Answers (2)

user3436435
user3436435

Reputation: 1

i think it's because you create a NSEvent using "WIDK" for parameter windowNumber , and WIDK is related to your app only.

Upvotes: 0

Nathan S.
Nathan S.

Reputation: 5388

Here is a better way to post keyboard events to the front-most application:

  CGEventRef a = CGEventCreateKeyboardEvent(NULL, 124, true);
  CGEventRef b = CGEventCreateKeyboardEvent(NULL, 124, false);
  CGEventPost(kCGHIDEventTap, a);
  CGEventPost(kCGHIDEventTap, b);

CGEventPost lets you determine where the event is posted. I used this code recently to allow someone to remotely control a PPT presentation on my laptop. (Character 124 is the right arrow key.)

Note that you should be freeing the event after posting it.

You can send to a specific app (eg not the front app) by using CGEventPostToPSN.

Upvotes: 1

Related Questions