It's hard to know exactly how much fidelity you're looking for with what happens for an actual click. For example, do you want the click to activate the app? Do you want the click to bring a window to the top? To make it key or main? If the location is in the title bar, do you want it to potentially close, minimize, zoom, or move the window?
As John Caswell noted, if you pass an appropriately-constructed NSEvent
to -[NSApplication sendEvent:]
that will closely simulate the processing of a real event. In most cases, NSApplication
will forward the event to the event's window and its -[NSWindow sendEvent:]
method. If you want to avoid any chance of NSApplication
doing something else, you could dispatch directly to the window's -sendEvent:
method. But that may defeat some desirable behavior, depending on exactly what you desire.
What happens if the clicked window's or view's response is to run an internal event-tracking loop? It's going to be synchronous; that is, the code that calls -sendEvent:
is not going to get control back until after that loop has completed and it might not complete if you aren't able to deliver subsequent events. In fact, such a loop is going to look for subsequent events via -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
, so if your synthetic events are not in the queue, they won't be seen. Therefore, an even better simulation of the handling of real events would probably require that you post events (mouse-down, mouse drags, mouse-up) to the queue using -[NSApplication postEvent:atStart:]
.
I think your first task is to really think deeply about what you're trying to accomplish, all the potential pitfalls and corner cases, and decide how you want to handle those.
With respect to the CGEvent...
stuff, you can post an event to a specific process using CGEventPostToPSN()
and that won't click on other app's windows, even if they are in front of the target window. However, it may still click on a different window within the target app.
Best Answer
Here is a working C program to simulate N clicks at a coordinate (X,Y):
Hosted at https://gist.github.com/Dorian/5ae010cd70f02adf2107