Screensaver idleTime help

Hi all.

I’m having an issue with idleTime on the Mac for a screensaver. I am running Sonoma and Xojo 3.1.

When I run my program, I use the commands

'reset the screen saver apple supplied
var resetTheScreensaverTime as New Shell
resetTheScreensaverTime.Execute ("defaults -currentHost write com.apple.screensaver idleTime 0”)
'resetTheScreensaverTime.Execute ("defaults -currentHost write com.apple.screensaver idletime 0”)

var mouseDownreadTheScreenSaverTime as New Shell
mouseDownreadTheScreenSaverTime.Execute ("defaults -currentHost read com.apple.screensaver idleTime”)

And it resets the idleTime to 0 (zero). Which can be seen in the screenshot below

Now just before my program ends, I run these commands to turn back ON the screensaver apple provided:

'reset the screen saver apple supplied
var resetTheScreensaverTime as New Shell
resetTheScreensaverTime.Execute ("defaults -currentHost write com.apple.screensaver idleTime 3600”)
'resetTheScreensaverTime.Execute ("defaults -currentHost write com.apple.screensaver idletime 3600”)

var mouseDownreadTheScreenSaverTime as New Shell
mouseDownreadTheScreenSaverTime.Execute ("defaults -currentHost read com.apple.screensaver idleTime”)

//quit the program
Quit

Yet the “start screensaver when inactive does NOT change to the time set.

3600 seconds is 1 hour, which is one of the apple drop down menu selectables.

The com.apple.screensaver (long mac address).plist shows the change, and that the file was hit based on the information part of the preview, and I see the time is what I set it to so the 64000 dollar question is: Why isn’t it changing?

I have tried everything and am even trying to understand launchd to kickstart the screensaver process, but I am really stumped.

Any help is appreciated.

"frohe weihnachten und ein gutes neues jahr!” to one and all.

Regards

What are you trying to accomplish by changing the idle time setting?

For example, if you are trying to prevent the actual OS screensaver from starting, there are better ways to do that…

Hi Mike.

That is EXACTLY what I am trying to do.

When I run MY screensaver, I DON’T want the default screensaver to run.
And when MY screensaver ends, at a user pre-determined time, turn back on the apple one.

I was reading something about UIKit, but I found it rather… confusing.

Regards

check out the command-line tool caffeinate

CAFFEINATE(8)                                   System Manager's Manual                                  CAFFEINATE(8)

NAME
     caffeinate – prevent the system from sleeping on behalf of a utility

SYNOPSIS
     caffeinate [-disu] [-t timeout] [-w pid] [utility arguments...]

DESCRIPTION
     caffeinate creates assertions to alter system sleep behavior.  If no assertion flags are specified, caffeinate
     creates an assertion to prevent idle sleep.  If a utility is specified, caffeinate creates the assertions on the
     utility's behalf, and those assertions will persist for the duration of the utility's execution. Otherwise,
     caffeinate creates the assertions directly, and those assertions will persist until caffeinate exits.

     Available options:
...

Hi Mike

Ah. you don’t know what you don’t know.

Thanks for the pointer. I’ll check it out.

Stay tuned!

hmmm… I wonder… Use declares to create a power manager assertion to force the display to stay awake while your screensaver runs, and then end the assertion when you want to allow the machine to sleep. Below is code from Sleep Aid that can be used to prevent the display from sleeping, use which ever declare library you have.

sleepPreventionToken = NSProcessInfo_beginActivityWithOptionsReason( NSProcessInfo_processInfo, _
NSActivityIdleDisplaySleepDisabled, "We be a testing this er thingamejig" )
NSObject_retain sleepPreventionToken

Then when you want to let the computer sleep.

NSProcessInfo_endActivity( NSProcessInfoCurrent, sleepPreventionToken )
NSObject_release sleepPreventionToken

Ideally you should use declares to modify other processes UserDefaults, in newer versions of the macOS this can trigger a Privacy warning.

Hi Sam.

I think that my explanation of what I can’t figure out might have been a little messed up from my end, so let me try and explain a little better. All of the answers and help I have gotten is great, and teaches me, so I am NOT complaining :smiley:

My problem is not with the display of the program turning off while my program is running.

My problem is my program runs for a user selected period of time, and during this time I do NOT want the built in apple screensaver starting. An example:

The user selects an end time for my program of let’s say 10 minutes.
If the apple screensaver is to kick in in 5 minutes, my program chugs along happily up to 5 minutes and then the apple screen saver kicks in.

So, I use the command
defaults -currentHost write com.apple.screensaver idleTime 0
to disable the apple screensaver.

And it works fine.

When my program ends and just before it actually quits, I want to turn back on the screensaver with:
defaults -currentHost write com.apple.screensaver idleTime 600

But it never resets to this value. It always shows in System Settings → Lock Screen

Screenshot 2024-12-03 at 9.34.52 PM

I have checked the file itself (/ByHosts/com.apple.screensaver (long flipping number).plist, and the created, changed, etc dates change to the run date and time.

This is what is confusing me. Why I will allow me to disable, but not enable.

Regards

Hi Guys.

Little update.

I was thinking about my problem, and thought “It could be my read / write syntax”, so I went to terminal and executed my commands.

The idleTime 0, as expected, worked perfectly, and the idleTime 3600 didn’t.

Now, because I’m old and have trouble finding files sitting right in front of me, I went and put a blue tag on the file so I could find it easily.

When I execute the commands, the blue tag on my file disappears.
And the permissions I gave to the group “everyone” gets reset to No Access, too.

Does that mean it is being re-created?

Regards

I think you are using the wrong approach - the caffeinate tool would be simpler and less invasive (it’s generally not a good thing to change a users’s preferences).

To answer your question, another way to tell if a file has been recreated is to look at the creation and modification times.

Hi Mike.

To be honest, caffeinate isn’t working for me, because my display is NOT shutting off before my program ends.

It is resetting the idleTime back to what it was WHEN the program ends.

Are you able to do it?
If so, how?

Regards

I’m only guessing here, but I wonder if using the -u and -t options might do it:

-u      Create an assertion to declare that user is active. If the display is off, this option turns the display
         on and prevents the display from going into idle sleep. If a timeout is not specified with '-t' option,
         then this assertion is taken with a default of 5 second timeout.

 -t      Specifies the timeout value in seconds for which this assertion has to be valid. The assertion is dropped
         after the specified timeout. Timeout value is not used when an utility is invoked with this command.

type
man caffeinate
in Terminal.app to get the full set of options

Okay, so if we’re just trying to control the idletime for the screensaver engine, there’s a couple of things that spring to mind.

  1. Use declares and NSUserDefaults to actually set the value, this way you can ensure that you’re passing an Int and not a string.
  2. Don’t worry about the actual preferences file, as Apple recommends you use the preference API, to avoid any problems with changes they may make (i.e. never directly edit files in the preferences folder). There’s an old neglected feedback request for accessing Apple preferences via the Xojo framework.
  3. We don’t know anything about the screensaver engine, it is possible that the System Settings is doing more than changing the preferences values.
  4. This post from 2008 seems to indicate that you need to restart the Apple screen saver engine after you change the values. Screen saver not completely controllable via "defaults write" | Mac Support

Just to better understand your problem.

  1. You replace the Apple screensaver with your own engine, that is triggered after a timeout.
  2. This screensaver runs for only a limited amount of time.
  3. Once it’s done (i.e. after 20 mins), you want the Apple Screen saver to take over from there?
1 Like

The 2024 version of that is
killall WallpaperAgent

See Understanding the macOS Sonoma screensaver plist - Managed Installation - iScreensaver Forum

I still maintain that messing with the users’s prefs is the wrong way to go about it, but like you I’m not sure exactly what this app is doing.

Kind of. Since the program isn’t 100% finished, what I want to do is, when the End time set by the user is reached, put the display to sleep and lock it ( THAT works fine) but RESET the screensaver inactive time. Why? Because the program isn’t finished.

As to:

NSUserDefaults to actually set the value, this way you can ensure that you’re passing an Int and not a string.

I am NOT a “trained” programmer. Everything I have learned is self taught, so there is much I don’t understand, such as NSUserDefaults. I have read what documentation I have found online but for now it goes over my head. An explanation and maybe an example would help.

Regards

I am not trained either, all self taught also :slight_smile: NSUserDefaults is one of the ways in which you can manipulate the app preferences correctly. There is an old Feedback request for it, but year after year it continues to be ignored. So you have to use either a declare library (such as my now unsupported AppKit) or a plugin.

In some languages accessing the preferences is as simply as annotating the property with “@AppStorage” which is super clean and easy, but I don’t see Xojo adding anything like this.