More control over the Windows screensaver

If you have a question or need help, this is the place to be.
Post Reply
User avatar
Boolean263
Plugin Developer
Posts: 84
Joined: Sat Aug 12, 2017 7:52 pm
Location: Ottawa, Canada
Contact:

More control over the Windows screensaver

Post by Boolean263 » Mon Oct 16, 2017 12:47 am

The System.Idle event is triggered by Windows believing the computer is idle, based on keyboard/mouse use. It doesn't take into account anything you might be doing on your computer that doesn't need input; specifically, watching videos. So if you tell EventGhost to do something when your computer is idle, it'll happily do that even if it interrupts your video.

The Windows screensaver mechanism is smarter than that. The screensaver won't trigger while you're watching a video. Unfortunately, EventGhost doesn't show an event triggered when the screensaver would activate.

I've done some googling around, and I found this helpful answer on StackExchange.

It lists two programs which you can use as your screensaver, and which you configure to run a program of your choice when the screensaver activates. Only one still seems to exist, RunSaver. You could install this screensaver, and then configure it to run `"C:\Program Files (x86)\EventGhost\EventGhost.exe" -event ScreenSaver` , and you'd get an EG event when the screensaver would kick in. You'll need to add your own call to your preferred screensaver when acting on this action, though. Fortunately, you can run your screensaver of choice with the System → Run Application action. Look for a file with the "*.scr" file extension, probably in C:\Windows\System32.

You still get no event when the screensaver would deactivate, but System.UnIdle is triggered at the same time, so that should be good enough.

The StackExchange answer also mentions that it should be possible for Windows to generate events when the screensaver is activated or deactivated, but that it requires you to manually enable it in something called "Local Group Policy Editor". My computer doesn't seem to have this (I can't find gpedit.msc) so I'm not able to test it out. In theory, if Windows generates events for it, then EventGhost should be able to do the same. If any of you experiment with that, I'd be interested in hearing the results.

Why would you want to know when the screensaver is triggering in the first place? Well, my main use case is to replace the screensaver. If I have iTunes running, I'd like to see its visualization instead of the normal screensaver. You might want to play a video or something instead.
Windows 10 Home, version 1703, build 15063.540 · EventGhost 0.5.0-rc4 · wxPython 3.0.2.0
Python programmer for fun and profit. Dabbler in EventGhost plugin writing. Wiki gardener. General geek.

Septik
Posts: 39
Joined: Sun Feb 15, 2015 1:29 pm

Re: More control over the Windows screensaver

Post by Septik » Mon Oct 16, 2017 6:59 am

That's awesome, been wanting something like this. Thanks for sharing!

I was able go the gpedit.msc route, and I now have the events "System.Monitor.Dim", "System.Monitor.Idle" (triggers right after "Dim") and "System.Monitor.On".

For those who don't have the group policy editor, check out this page. Seems like you can enable it by running a simple batch file (no third party software will be used). For what my judgment's worth, it looks safe, but do open it yourself and look at it if unsure.

User avatar
kgschlosser
Site Admin
Posts: 5341
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: More control over the Windows screensaver

Post by kgschlosser » Mon Oct 16, 2017 8:28 am

create a macro with the Python Script action
past the code below into the action.
add the event Main.OnInit

you can execute the script manually but after that it will run automatically each time EG starts.

No additional software needed

Code: Select all

import threading
import win32gui
import win32con

class ScreenSaverThread(object):

    def __init__(self):
        self._event = threading.Event()
        self._thread = threading.Thread(name='ScreenSaverThread', target=self.run)
        self._thread.start()

    def run(self):
        eg.Bind('Main.OnClose', self.stop)
        old_state = win32gui.SystemParametersInfo(win32con.SPI_GETSCREENSAVERRUNNING)
        
        while not self._event.isSet():
            new_state = win32gui.SystemParametersInfo(win32con.SPI_GETSCREENSAVERRUNNING)
            
            if new_state != old_state:
                old_state = new_state
                suffix = 'Activated' if new_state else 'Deactivated'
                eg.TriggerEvent(prefix='ScreenSaver', suffix=suffix)
            self._event.wait(0.5)
        eg.Unbind('Main.OnClose', self.stop)

    def stop(self, dummyEvent=None):
        self._event.set()
        self._thread.join(1.0)
        return False

eg.globals.screenSaverThread = ScreenSaverThread()
If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 5341
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: More control over the Windows screensaver

Post by kgschlosser » Mon Oct 16, 2017 9:12 am

Septik wrote:
Mon Oct 16, 2017 6:59 am
For those who don't have the group policy editor, check out this page. Seems like you can enable it by running a simple batch file (no third party software will be used). For what my judgment's worth, it looks safe, but do open it yourself and look at it if unsure.
This is a safe batch file. all it does is leverage dism to install the packages from windows it's self.

or you can simply copy the gpedit.msc out of your syswow folder into your system32 folder.
If you like the work I have been doing then feel free to Image

User avatar
Boolean263
Plugin Developer
Posts: 84
Joined: Sat Aug 12, 2017 7:52 pm
Location: Ottawa, Canada
Contact:

Re: More control over the Windows screensaver

Post by Boolean263 » Mon Oct 16, 2017 10:35 am

Septik wrote:
Mon Oct 16, 2017 6:59 am
For those who don't have the group policy editor, check out this page. Seems like you can enable it by running a simple batch file (no third party software will be used). For what my judgment's worth, it looks safe, but do open it yourself and look at it if unsure.
Cool, thanks for sharing that! I was able to make it work with that batch file. I don't get the events you mention in EventGhost, however.

So that means it's time for me to write another plugin. (: When I get my next bout of free time, I want to see about creating one that monitors the Windows event log. This StackOverflow question has a method I can try.
Windows 10 Home, version 1703, build 15063.540 · EventGhost 0.5.0-rc4 · wxPython 3.0.2.0
Python programmer for fun and profit. Dabbler in EventGhost plugin writing. Wiki gardener. General geek.

User avatar
Boolean263
Plugin Developer
Posts: 84
Joined: Sat Aug 12, 2017 7:52 pm
Location: Ottawa, Canada
Contact:

Re: More control over the Windows screensaver

Post by Boolean263 » Mon Oct 16, 2017 10:37 am

kgschlosser wrote:
Mon Oct 16, 2017 8:28 am
create a macro with the Python Script action
past the code below into the action.
add the event Main.OnInit

you can execute the script manually but after that it will run automatically each time EG starts.

No additional software needed
Thanks for sharing that! It's a pretty straightforward approach. I'll probably change the wait() call when I try it out, though. The screensaver activates on a minute-by-minute schedule, so polling its status twice a second seems like a bit of overkill. (:

I'm also not a huge fan of polling loops, so at some point I'm also going to see about writing an event log watching plugin. Do you know if such a thing already exists?
Windows 10 Home, version 1703, build 15063.540 · EventGhost 0.5.0-rc4 · wxPython 3.0.2.0
Python programmer for fun and profit. Dabbler in EventGhost plugin writing. Wiki gardener. General geek.

User avatar
kgschlosser
Site Admin
Posts: 5341
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: More control over the Windows screensaver

Post by kgschlosser » Mon Oct 16, 2017 3:17 pm

I do not know if an Event Log plugin. but what i do know is that it's a huge pain to do because of security descriptors. Now I am not a big fan of the polling loop either. and i set it to 0.5 seconds because at that speed there is negligible impact on system resources. there isn't enough of a difference in CPU cycles between 1/2 a second and 3 seconds.
If you like the work I have been doing then feel free to Image

Post Reply