mlaily/NegativeScreen

add a timer to activate the filter during a certain timespan (bedtime)

roiwirven opened this issue · 3 comments

this is more like an additional feature suggestion rather than an issue

I came here through this topic: https://superuser.com/questions/1360248/is-there-any-way-to-script-windows-10s-color-filter-feature-programmatically
and I had exactly the same issues as the op.

so, I discovered your software but i saw there were no option to enable the filter only at a given time.

after servals hours (i only have basic knowledges in programming, and i don't know the .NET framework at all), i finally added a few lines of codes to the source and set the program to be launched at startup in order to solve the problem (which was exactly the one described by the op of the linked topic)

that being said, my implementation of this feature is very crappy: i hardcoded the time values, and, as i didn't know how the program was organized, i don't think i put my piece of code at the right location regarding how the program was structured, and that's why i didn't pulled my changes.

but as I think those changes may be useful for other people, I think it would be nice if you could add this feature to your software in the proper way.

here is the function I just added (so that you can just copy it and add it at the right place of the software:

new variable (in overlay manager)

private System.Timers.Timer TimeCounter;
private int AwakeTimeHour;
private int BedTimeHour;

new lines of code in OverlayManager() (before the InitializeControlLoop() instruction)
TimeCounter = new System.Timers.Timer();
RefreshTimer();
TimeCounter.Elapsed += (sender, e) => RefreshTimer();
TimeCounter.Start();

new function (in overlay manager)
private void RefreshTimer()
{
DateTime TimeStamp = (DateTime.Now);
if (TimeStamp.Hour < AwakeTimeHour)
{
Enable();
TimeCounter.Interval = ((((AwakeTimeHour- TimeStamp.Hour) * 60 - TimeStamp.Minute) * 60 - TimeStamp.Second) * 1000);
}
else if (TimeStamp.Hour < BedTimeHour)
{
Disable();
TimeCounter.Interval = ((((BedTimeHour - TimeStamp.Hour) * 60 - TimeStamp.Minute) * 60 - TimeStamp.Second) * 1000);
}
else
{
Enable();
TimeCounter.Interval = ((((24 + AwakeTimeHour- TimeStamp.Hour) * 60 - TimeStamp.Minute) * 60 - TimeStamp.Second) * 1000);
}
}

this implementation is not perfect, as I mentioned previously, it needs some features to be integrated properly, in particular to be able to activate it/disable it, change the Awake Time/Bedtime, and select a filter (or no filter) for night and day.

Also, in the same vein, i tried, to disable the trayIcon (in order to take away a bit further the temptation of just disable the filter when it's time to sleep), but when i tried just to put trayIcon.Visible = false or this.ShowInTaskbar = false; it didn't work (maybe I put them in the wrong place). and, as you know the software much better than me, I think it would be a good addition to the software if there were an option to hide this icon (in the .conf file so that no one will activate it by mistake then not knowing how to disable it), and then, it may really look like there was a native implementation of the night time lightening on windows

well, that was a long message, I hope I didn't give you too much work, and thank you for your software, you already did an amazing job :)

Hello,

I feel like the time based transition would work well only if it were very progressive, like what Windows of f.lux do. For NegativeScreen, it makes less sense, especially since it costs nothing to just press the hotkey combination to do it manually, right?

That said, there is a built-in http api in NegativeScreen that can be used to do this kind of thing.
I think the best way to execute some action at a given time is the Windows Task Scheduler.

Combining these two things you can:

  • Enable the NegativeScreen http api (set EnableApi=true in the conf. It's set to false by default`)
  • Make sure NegativeScreen.exe is always running in the background, maybe by adding it to the Windows startup folder.
  • Create a new scheduled task to run powershell -Command &{ Invoke-RestMethod http://localhost:8990 -Method POST -Body ENABLE } when you want to enable NegativeScreen, and another one to disable it by sending a DISABLE body in the command instead of ENABLE.
  • That's it!

Here is a little post documenting the same idea to toggle between light/dark themes: https://zerowidthjoiner.net/2020/04/11/how-to-automatically-switch-between-windows-10-light-and-dark-themes — there are hundreds of other examples on the web if you need them.

Be aware that since the earth is tilted on its axis, you will probably have to adjust the scheduled start and end time several time a year if you want it to keep up with the daily sunlight exposition you get where you live...

Regarding the tray icon, it's there so it's still possible to exit the app even if the user doesn't know the right key combination, so allowing to make it invisible is not part of my plans! :p

But of course you have the source code, so feel free to adapt it to your needs!
I'm not sure why setting Visible = false was not enough, but removing it entirely can be done here https://github.com/mlaily/NegativeScreen/blob/master/NegativeScreen/OverlayManager.Designer.cs#L118 (just delete the variable definition and all the code related that won't compile anymore)

In fact, the point of this feature is more to prevent "screen addiction" rather than "eye strain".
The fact is that a black and white screen is much less attractive than a colored one, and the idea is that this feature would be a middle ground between doing nothing and rely on oneself to stop the computer at the right time and just shut down the computer directly at a given time (the good aspect of this solution is that it makes the screen much less attractive to play videogames or idle on the internet but don't goes much in our way if we try to work or doing productive things + as it don't shutdown the computer directly, it enables us to finish the game or the discussion in progress before leaving).
also, activating the filter manually requires much more mental effort and self-discipline than just having the screen turning black and white by itself, and as this feature is here to help those with low self-discipline, activating it automatically is the whole point of it.
also, about hiding of the tray icon, the idea was to take further away the temptation of just disable it on one shortcut or one click when it's bedtime, and I think that if you restrict this option to be enabled only through manual edit of the conf file, it may not create too much problem (if someone know how to manually activate it, he also knows how to manually disable it or access the task manager to shut down the software in last resort)

This feature already exist in smartphone but not in windows, and seeing that the topic I linked got 6 likes, it means that at least 6 other people + the guy who made the topic also miss that feature (but I think the actual number is much higher, as I, for example, googled the topic but had no account to upvote, so if one day, you add this feature natively on your software, I am convinced that at least one person [other than me] would make use of it and being grateful not to have to make additional coding to get it)

that being said, thank you for your solutions, I didn't know one could create a script that directly interact with an app like that. I also don't know if a lot of software support such feature, but it seems kinda cool. I think I will keep with my solution as it already works just fine, but thank you

also thank you for the tray icon removal tip, it works fine, and now, it feels like the "Digital Wellbeing" feature from android was natively included on my windows computer. Thank you

Ok, I understand better the reason why you were asking these things.
Thanks for sharing your insights!