How is CGRequestPostEventAccess supposed to work?

I can't find any documentation on CGRequestPostEventAccess or its friend CGRequestListenEventAccess, except for the API declarations in CGEvent.h. The fact that it returns a boolean and doesn't have a completion callback or anything like that suggests that it should be synchronous, i.e., not return until the user has decided to grant or deny permission. Experimentally, that doesn't seem to be the case, but then what does the return value mean?

It’s been a while since I played around with this but…

The fact that it returns a boolean and doesn't have a completion callback or anything like that suggests that it should be synchronous

That’s my recollection.

what does the return value mean?

Whether you were granted access.

Note that the framework prevents you from requesting multiple times.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Experimentally, CGRequestPostEventAccess is not synchronous. Even if it has opened an alert offering to take the user to System Settings to grant access, it returns NO in a millisecond or so.

I was also confused by the fact that the related function CGPreflightPostEventAccess just seems to report the access that the process had when it launched, even if the access shown in System Settings changed while the process was running.

That was beginning to make me believe that changes in trust while a process is running don't affect the process at all, but that seems not to be the case: If an agent is initially trusted to post events, and installs an event tap, but trust is revoked while it's running, then the Mac becomes mostly unresponsive to keyboard events.

I've submitted FB11832484 requesting documentation on these APIs.

Note that the framework prevents you from requesting multiple times.

I'm guessing you mean that repeated calls to CGRequestPostEventAccess will silently fail, but please let me know if there is some other form of "prevention".

Experimentally, CGRequestPostEventAccess is not synchronous.

Interesting. It’s definitely issuing a request to TCC synchronously. I suspect what’s going on is that TCC is deciding to return an interim value while it waits for the user to decide.

That was beginning to make me believe that changes in trust while a process is running don't affect the process at all

Right. This is why, when you grant access via System Settings, it offers to relaunch the app.

but that seems not to be the case

There’s definitely some wiggle room here. Some TCC-gated APIs see changes immediately and some don’t. In a complex system like CG, I can imagine there are cases where it varies based on how your process is using CG.

I've submitted FB11832484 requesting documentation on these APIs.

Thanks.

I'm guessing you mean that repeated calls to CGRequestPostEventAccess will silently fail

Well, “fail” is a bit harsh. They will silently return the previous result.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

How is CGRequestPostEventAccess supposed to work?
 
 
Q