CGEventTapCreateForPid fails to get event tap

My app uses CGEventTapCreateForPid to monitor keyboard events of a corresponding process. My app has already enabled the Accessibility permission, and AXIsProcessTrustedWithOptions returns true. However, CGEventTapCreateForPid returns null. What could be the problem? Does anyone know? I tested and found that if CGEventTapCreateForPid returns null, I can reset the Accessibility permission using tccutil reset Accessibility myapp_bundleid without restarting my app. But my app can still get the permission through AXIsProcessTrustedWithOptions

Replies

This seems to be working for me. To start, I created an app wrapped around the CGEvent code from this post. I then tweaked the code to target a process ID rather than the system as a whole:

func start(pid: pid_t, _ setStatus: @escaping (String) -> Void) {
	…
	guard let port = CGEvent.tapCreateForPid(
		pid: pid,
		place: .headInsertEventTap,
		… everything else the same …

I then updated my app to call this, targeting TextEdit’s pid (which I got via the NSWorkspace > runningApplications > processIdentifier chain).

When I ran the app for the first time and clicked the Start button, I got the TCC prompt. I went to System Settings > Privacy & Security > Input Monitoring and enabled the app. I then stopped the app and ran it again. This time everything worked. I switched to TextEdit and pressed a key and it was logged by my app.

This is on macOS 14.4 using Xcode 15.3.

My test app wasn’t sandboxed.

Share and Enjoy

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