I have a window that includes a listbox… which gets updated periodically… If the Mac’s screen saver comes on while the app is running then it seems that the listbox updates all get buffered… and once the screen saver is turned off, you see all the updates happen in the listbox.
Is this expected? Is there a way to prevent this from happening and just have the list box display the most recent update?
Yes, screen output is locked when a screensaver is running.
Best thing would be to use a DistributedNotificationCenter and monitor the global screensaver notifications like here: http://stackoverflow.com/questions/16944434/monitoring-screensaver-events-in-osx
Thanks for the info… but I am not sure how that helps. I can listen for the notification that the screensaver is turned on but I want to update the listBox even when the screensaver it turned on
I do not want the user to have to sit and watch all the flickering while the listBox updates once they turn the screen saver off.
First thing I would do is to verify the timer still runs while the screen saver is on. You did not tell the period of the timer, but it is easy to place a System.Debuglog in the Action even that prints microseconds, ticks, or totalseconds.
Yes, it appears that timers still fire when the screensaver is turned on.
I have no idea how the timer updates the listbox, but would it not be possible to halt it during the screen saver and resume afterward, so only the last update happens.
Alternatively, you could cover the listbox with an invisible canvas. When screensaver comes on, drawinto the listbox and make it visible. Then make it invisible again after the listbox is finished updating.
Why do you want to update the listbox during screensaving? Do you have a screensaver that shows through to the desktop? Otherwise, when the screensaver starts then stop updating the listbox so it’s not buffered. When the screensaver stops then update the listbox with current values.
Yes, I can do something like that… but there are actually 2 listboxes… one of them existing rows/cell values are just updated and “throwing out” all but the last update while the screensaver is on would work… But in the other listbox new rows are added and it would be much better if the user did not have to wait for what could be hundreds of new rows to be displayed…
I’m not able to reproduce the problem so I can’t tell what’s really happening. I ran a Timer that adds a row and beeps and I can hear it beep during screensaving and all the rows are there when leaving the screensaver.
Possibly something else is bottling up, like a socket or such. What is it that periodically updates the listbox with new rows? Can you confirm that this mechanism is running and adding rows during the screensaver? Or maybe it only runs after the screensaver so it just looks like the listbox is catching up but it’s the updating mechanism that’s buffered.
Still, a few hundred rows shouldn’t take long to add. It’s not until a few thousand that I notice a slowdown. If you need to, while the screensaver is running you can store new rows in a property and then when the screensaver ends add all the stored rows to the listbox in one fell swoop.
After a lot of testing it seems that the screensaver is not actually blocking the listbox updates… but it is slowing them down.
I put a “beep” in the listbox CellTextPaint event and when the screensaver is off it beeps at the regular interval I would expect. But when the screensaver is on the beeping slows down considerably… and the interval between beeps varies greatly. So it seems that the updates to the listbox are coming in faster than they can be processed and they start accumulating… Once I turn off the screensaver I see the accumulated updates execute very quickly…
This could be App Nap kicking in. I don’t know the best way to turn that off. See this link for some ideas.
Why not just exit the celltextpaint events if the screen saver is running ?
Once it stops your entire listbox will get paint events for everything & it will update ASAP
After some more work it does turn out to be an App Nap issue… thank you Will.
If I add in the app open event:
SleepDisableHandle = NSProcessInfoMBS.processInfo.beginActivity(NSProcessInfoMBS.NSActivityBackground, “Sync running”)
… then the problem goes away.