Capture Screen pre-login contex on macOS 15 Sequoia

Hello,

Since 2017 I provide a free and open source Remote Desktop for macOS, Windows and Linux that supports macOS 10.7 to macOS 15. Screen capture is done with CGDisplayCreateImage and works fine. But there is a problem on macOS 15 Sequoia I can not capture the screen in the pre-login context (I am referring to the login screen before the user access into his account). The screen capture in pre-login context works fine for all macOS versions except macOS 15 Sequoia. In last weeks I tried to fix the issue without success:

  • tried CGDisplayStream
  • tried AVCaptureScreenInput
  • tried ScreenCaptureKit
  • tried to sign the App (and executable)

None of these work before the user login, but them works only when the user is logged in.

Additional info:

  • I run the App with "launch agent" when user is connected.
  • I run the App with "launch daemon" when user is not connected.

Any help would be greatly appreciated!

Answered by DTS Engineer in 813214022

Hmmm, there’s a lot to unpack here.

I run the App with "launch daemon" when user is not connected.

You should not be doing this from a launchd daemon ever. It has no business connecting to the window server. Rather, use a pre-login agent. See PreLoginAgents, which is super old but shows the right overall path.

I’m also concerned about you “run the App” comment. It sounds like you’re running your main app in these contexts. That’s not a great idea. You are much better off separating out the agent-y stuff into a separate agent and then embed that in a GUI app. Running a full GUI app in, say, the pre-login context is likely to trigger all sorts of odd behaviour.

Plus, pre-login agents run as root and you really don’t want to run an entire GUI app as root.

Beyond that, macOS 15 changed the way that the System Settings > Privacy & Security > Screen & System Audio Recording privilege is managed. The exact policy changed during the macOS 15 beta and early release cycle. There’s also a new com.apple.developer.persistent-content-capture entitlement for screen sharing products.

Share and Enjoy

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

Hmmm, there’s a lot to unpack here.

I run the App with "launch daemon" when user is not connected.

You should not be doing this from a launchd daemon ever. It has no business connecting to the window server. Rather, use a pre-login agent. See PreLoginAgents, which is super old but shows the right overall path.

I’m also concerned about you “run the App” comment. It sounds like you’re running your main app in these contexts. That’s not a great idea. You are much better off separating out the agent-y stuff into a separate agent and then embed that in a GUI app. Running a full GUI app in, say, the pre-login context is likely to trigger all sorts of odd behaviour.

Plus, pre-login agents run as root and you really don’t want to run an entire GUI app as root.

Beyond that, macOS 15 changed the way that the System Settings > Privacy & Security > Screen & System Audio Recording privilege is managed. The exact policy changed during the macOS 15 beta and early release cycle. There’s also a new com.apple.developer.persistent-content-capture entitlement for screen sharing products.

Share and Enjoy

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

Thanks for the reply.

I’m also concerned about you “run the App” comment.

Sorry for my incomplete information. I run the service in "launch daemons". When user login I start ather process in user context "launch agents" and the capture screen is done in user context except when user is not logged in this case the service do the screen capture. After your suggestion I tried to use PreLoginAgents but under Sequoia it still does not work.

I requested entitlement com.apple.developer.persistent-content-capture, I hope I can get permission and that this solves my issue.

Any other help would be greatly appreciated!

Capture Screen pre-login contex on macOS 15 Sequoia
 
 
Q