How to programmatically simulate a mouse click without moving mouse in Cocoa

Dany Joumaa picture Dany Joumaa · Aug 25, 2012 · Viewed 9.5k times · Source

I am interested in simulating a mouse click event/keyboard stroke on Mac OS X without actually moving the mouse.

In Windows, it is possible to do this using messages:

win32: simulate a click without simulating mouse movement?

Is there an analog of this for Mac OS X? I am aware of Quartz Event Services, but it seems that that API would only restrict me to sending events to the current key window. Is this true? Is it possible to send keyboard/mouse events to non-key windows? I really just need to be able to send a keyboard command to another app.

Answer

Dorian picture Dorian · Nov 14, 2015

Here is a working C program to simulate N clicks at a coordinate (X,Y):

// Compile instructions:
//
// gcc -o click click.c -Wall -framework ApplicationServices

#include <ApplicationServices/ApplicationServices.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  int x = 0, y = 0, n = 1;
  float duration = 0.1;

  if (argc < 3) {
    printf("USAGE: click X Y [N] [DURATION]\n");
    exit(1);
  }

  x = atoi(argv[1]);
  y = atoi(argv[2]);

  if (argc >= 4) {
    n = atoi(argv[3]);
  }

  if (argc >= 5) {
    duration = atof(argv[4]);
  }

  CGEventRef click_down = CGEventCreateMouseEvent(
    NULL, kCGEventLeftMouseDown,
    CGPointMake(x, y),
    kCGMouseButtonLeft
  );

  CGEventRef click_up = CGEventCreateMouseEvent(
    NULL, kCGEventLeftMouseUp,
    CGPointMake(x, y),
    kCGMouseButtonLeft
  );

  // Now, execute these events with an interval to make them noticeable
  for (int i = 0; i < n; i++) {
    CGEventPost(kCGHIDEventTap, click_down);
    sleep(duration);
    CGEventPost(kCGHIDEventTap, click_up);
    sleep(duration);
  }

  // Release the events
  CFRelease(click_down);
  CFRelease(click_up);

  return 0;
}

Hosted at https://gist.github.com/Dorian/5ae010cd70f02adf2107