Hi, I have a Xojo program that is otherwise working that is capable of sending eMail automatically when a specified time is reached. It appears to send OK in all cases except when password protection is enabled. That is, it sends OK if the screen is active, and it sends OK when the screen is sleeping, but it does not send once the password requirement of the screen sleep activates. In that case, it doesn’t send the message until you log back in and you send a message manually. That is, the message is apparently queued for sending, but not sent until some other mail activity occurs.
Does this make sense to anyone and is there a fix?
I have a really really bad hack idea for a fix. Prevent sleep with caffinate. Your app will need Full Disk Access for this to work. If you don’t have an interest in adding it to your app, there are existing apps that implement the same thing: Caffeine - IntelliScape Solutions
caffeinate -u prevents all of that because that’s what it’s for. The effect is like moving your mouse a pixel each second (but that’s not actually how it works). Screen stays awake and out of password mode.
Works in situation similar to 1, except I normally start the screensaver with the hot corner
Fails in situation similar to 2, where the require password time has passed
3 and 4 don’t apply
This is an old Mac Mini (early 2009) with MacOS 10.11.6 … I’m practically sure it used to work and may have have broken without my noticing after an upgrade.
The program is supposed to notify my family if I don’t interact with it daily.
Pretty much my thinking. Of course I don’t want the computer completely unsecured when I’m out (or lying unconscious on the floor, but maybe that wouldn’t matter
I have fooled with options to suppress the reduction of CPU time allowed, though I forget why now
So I’ve been thinking about this for a while, especially as I’ve been doing a lot of researching into Mac sleeping habits for the last 6 months.
I suspect the way in which this could work (and even if the Mac goes to sleep) is to create a privileged helper that is constantly running (using something like launchd or coreduet). Because this helper was launched with admin permissions, I would expect it to not have the same restrictions as a normal application.
The complication comes from that most of the Apple privileged helpers identity as XPC services. This may or may not be possible from Xojo, they also require encrypted communications between the GUI and helper (XPC). Now in theory it should be possible to create a normal helper and have the OS elevate it’s privileges, you could also use your own encryption methods for exchanging configuration data over IPC or shared memory, heck even using NSUserDefaults. However as this helper permanently has admin privileges, you need to be careful that it doesn’t become a vehicle used to hijack your computer.
Apple considers this much safer than having a normal application run some code in a time limited privileged block, maybe it is, but I don’t feel that it is.
There is private API that an application can use to schedule a DisplayWake.
Addendum 2:
Even if you get the machine to wake on it’s own, unless you disable the password requirement, it will still be “locked”.
So my suggestion goes as follows.
Create a helper application in Xojo that either sends a fixed message or has a secure method for obtaining a message to send.
Utilize the deprecated (but still working) Authorize classes (MBS has these and there’s probably an API 1.0 example out there). To request authorization while the machine is unlocked, store the authorization token. You’ll need to enter in your account password.
Have your application determine when it is the correct time to send the message (it should still fire when the Mac is asleep thanks to PowerNap (PowerNap runs once an hour on Intel and 3~6 times an hour on M1). Then use the authorize token to launch the helper with privileges to send the message.
The above is untested and may not even work, but it’s what I can see you can do with the least amount of work.
3a. If needed, it should possible using private API to create a DisplayWake power management assertion that will wake the screen (like it does to handle Notifications). Once the helper has sent the message, timed out or encountered an error, you release that assertion and it should go back to sleep.
You should be fine as long as you don’t intend for your application to last (who does with Apple’s rabid pace of change) or to distribute it via the Mac App Store (you’ll get into trouble for using Private API).