Screen saver screen grabbing

Fucking Apple.

It seems that the XScreenSaver hacks that grab the desktop are no longer able to do that on macOS 11. They just get the background image, not a screenshot.

Is there something I can put in the plist to request such access? On iOS you can use things like NSPhotoLibraryUsageDescription to make it pop up a dialog requesting access to photos. Does macOS have something like that? (Though even if it did, I'll bet it would only work for apps, not .saver bundles... Sigh...)

It turns out that adding "/System/Library/Frameworks/ScreenSaver.framework/PlugIns/legacyScreenSaver.appex" to "System Preferences / Security / Privacy / Screen Recording" fixes it -- but is there some shell command that my installer can use to do that automatically?

(Oddly, after adding it manually, it does not show up in the list. But the savers are now able to grab the screen.)

Tags: , , , ,

16 Responses:

  1. jr says:

    the first line is the sum of the whole blog post.
    they seem to be unable/unwilling to create systems, which last. not that others are much better there. they all live from selling products and not from supporting/documenting them.

  2. Nate says:

    Screen Recording protection is a bit clunky on macOS. There's no option to do it via a plist, but this is a good overview of how to request it programmatically:

    https://www.ryanthomson.net/articles/screen-recording-permissions-catalina-mess/

    The user will still have to follow that dialog to SysPrefs in order to enable screen recording access but your request should have your app filled in with the unchecked box next to it.

    • jwz says:

      Huh. Well I had hoped that doing this would cause it to pop up that dialog on behalf of ScreenSaverEngine, or of System Preferences, but it does not:

      CGDisplayStreamRef ignored = CGDisplayStreamCreateWithDispatchQueue (CGMainDisplayID(), 1, 1, kCVPixelFormatType_32BGRA, nil, dispatch_get_main_queue(), nil);

      When testing this on my 11.6.1 development machine, I did get it to pop up the dialog on behalf of SaverRunner (my testing framework that loads and runs .saver bundles the way that ScreenSaverEngine does) but it doesn't do anything on my 12.0.1 test box. I don't know if this is an OS version thing, or something else. I see this in the system log, but I have no idea what it means:

      tccd: [com.apple.TCC:access] Handling access request to kTCCServiceScreenCapture, from Sub:{com.apple.ScreenSaver.Engine.legacyScreenSaver}Resp:{<TCCDProcess: identifier=com.apple.ScreenSaver.Engine.legacyScreenSaver, pid=1522, auid=503, euid=503, binary_path=/System/Library/Frameworks/ScreenSaver.framework/PlugIns/legacyScreenSaver.appex/Contents/MacOS/legacyScreenSaver>}, ReqResult(Auth Right: Unknown (None), DB Action:None, UpdateVerifierData)

      • jwz says:

        Wait, no, this time it did pop up the dialog for SaverRunner on 12.0. So that worked... but it's still not happening for ScreenSaverEngine.

        • Nate says:

          You're a bit beyond my understanding at this point. I hope you're using tccutil to reset permissions in between your tests so that the existing response isn't affecting things.

  3. Moofie says:

    Having just got bit by permissions in MacOS Catalina for AppleScript the new regime is a pain. There was a good talk at WWDC 2019 about what triggers permissions in MacOS 10.14 versus 10.15+.

  4. Derpatron9000 says:

    I think we are long overdue a 'fucking Apple' tag.

  5. Amy says:

    On a related note: Any chance of getting a macOS build for Apple Silicon anytime soon? I tried to install xscreensaver from the App Store on my new M1 Mac Mini and got the iPad version. This was...not what I expected.

    Or should I just download the .dmg from this site and hope the screen savers can hook in well enough using Rosetta? (Anyone else tested this?)

    • jwz says:

      Wow, so searches in the macOS store are returning iOS programs now? That's going to be interesting.

      XScreenSaver is not in the macOS App Store because there is no mechanism for distributing screen savers through the store. No, really! The only things that Apple lets you distribute through their store are single .app bundles. If your program needs to have an installer, or consists of more than one bundle, or is not an .app bundle, you cannot list it on the store. And if you tried to make an .app that was secretly an installer I'm 99% sure they'd reject that, too.

      Download the .dmg.

      6.02 contains M1 code (I'm pretty sure). 6.00 did not but it ran at 100% speed under Rosetta 2 (I'm pretty sure).

      • Amy says:

        Yes, iPad apps are appearing in the macOS App Store now.

        Screen capture of App Store listing. (explicitly says, "Designed for iPad. Not verified for macOS.")

        Screen capture of that version of xscreensaver. (showing app window with "about" dialog over it)

        I don't know if this is specific to Apple Silicon Macs, but it may be. It does stand to reason, though, that Apple is thinking in terms of some sort of convergence. This is on a 2020 M1 Mac Mini running macOS Monterey 12.0.1.

        Obviously, this wasn't what I wanted, so I'm going to dump that version and install from your .dmg.

      • Tim says:

        M1 Macs can run iOS software, yes. It's opt-out; if you don't like iPad XScreenSaver being listed on the Mac App Store, there's a way for you to flag it as Mac incompatible. I don't know anything about the details of how you do this.

        As you can imagine, controls are a little wonky. They've emulated touchscreen input using the trackpad, and it's not perfect. There's some UI API work they've been rolling out the past few years which seems aimed at eventual convergence.

Leave a Reply

Your email address will not be published. But if you provide a fake email address, I will likely assume that you are a troll, and not publish your comment.

You may use these HTML tags and attributes: <a href="" title=""> <b> <blockquote cite=""> <code> <em> <i> <s> <strike> <strong> <img src="" width="" height="" style=""> <iframe src="" class=""> <video src="" class="" controls="" loop="" muted="" autoplay="" playsinline=""> <div class=""> <blink> <tt> <u>, or *italics*.