Trouble clicking via CGEventPostToPSN()
Trouble clicking via CGEventPostToPSN()
- Subject: Trouble clicking via CGEventPostToPSN()
- From: Jean-Philippe Ouellet <email@hidden>
- Date: Mon, 19 Mar 2012 22:41:48 -0400
Hello,
First, sorry for the length, but I felt it necessary to illustrate with
example code.
I need to send events to an arbitrary process (not necessarily the front
one), preferably without needing to bring that process's window to the
front.
The following code works for sending a mouse click and letting the
window server decide where to send it to:
CGEventRef down = CGEventCreateMouseEvent(
NULL,
kCGEventLeftMouseDown,
CGPointMake(16, 36),
kCGMouseButtonLeft
);
CGEventRef up = CGEventCreateMouseEvent(
NULL,
kCGEventLeftMouseUp,
CGPointMake(16, 36),
kCGMouseButtonLeft
);
CGEventPost(kCGHIDEventTap, down);
CGEventPost(kCGHIDEventTap, up);
CFRelease(down);
CFRelease(up);
I can send mouse click events via CGEventPost() just fine, but that
requires the target window to have focus (which I am trying to avoid).
I can send key-press and mouse-move events via CGEventPostToPSN() just
fine (specifying which process to send the events to, instead of leaving
it up to the window server), the trouble only arises with is mouse
down/up events.
The following code (pretty much the above, the only difference being
that I specify myself which process to send the events to) does not work
and I don't even know how to find out where it breaks down.
if (GetFrontProcess(&psn) != noErr) {
// Only getting front process for simplicity in this example.
// It will usually be some process in the background.
printf("Unable to get front process\n");
return 1;
}
sleep(3); // Allow the user to switch processes
// so the front process is no longer the front process.
// Again... it's just for this simplified example.
CGEventRef down = CGEventCreateMouseEvent(
NULL,
kCGEventLeftMouseDown,
CGPointMake(16, 36),
kCGMouseButtonLeft
);
CGEventRef up = CGEventCreateMouseEvent(
NULL,
kCGEventLeftMouseUp,
CGPointMake(16, 36),
kCGMouseButtonLeft
);
CGEventPostToPSN(&psn, down);
CGEventPostToPSN(&psn, up);
CFRelease(down);
CFRelease(up);
According to the documentation[1] this is (as far as I can tell) exactly
how it is supposed to be done.
I suppose it would make some sense if the window server would allow me
to send keyboard events to stuff in the background, but no mouse-related
events at all (quirky, sure, but at least consistent), but I can send
mouse move events to stuff in the background with:
CGEventRef move = CGEventCreateMouseEvent(
NULL,
kCGEventMouseMoved,
CGPointMake(x, y),
kCGMouseButtonLeft // ignored
);
CGEventPostToPSN(&psn, move);
CFRelease(move);
and they work no problem. So I am at a loss for what is wrong here.
I've been stuck on this for a few days now, and I can't seem to figure
it out, and I can't find any example code which accomplishes this
without temporarily bringing the desired window to the front and then
sending it back as soon as the event has been sent (a very ugly hacky
unprofessional-looking solution).
I have tested this code on Snow Leopard and on Lion, with the same results.
Could somebody who has had success with clicking to background processes
please shed some insight on the proper way to accomplish this?
[1]
https://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html
Many thanks,
Jean-Philippe Ouellet
P.S: Not sure if this belongs in accessibility-dev or in quartz-dev, but
I figured that since most of the stuff on the quartz-dev archives is
about graphical output, and not much about the event API, so I figured
this would be the best place. If there is a better place though, please
do let me know, I'm new around here.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Accessibility-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden