At the end of 2014 I decided that it would be interesting to spend some time researching the history of screensavers as a web project, and ever since then I've spent a decent chunk of my spare time on the project. My original plan was to generate a list of interesting screensavers, spend some time analyzing each one, and maybe implement a version in Processing or p5.js.
Current plan for next year is to make a screensaver-a-week #somethingaweekin2015— colin mitchell (@muffinista) December 23, 2014
I liked the results of my early efforts, and I drafted a few blog posts about what I learned. But then I decided that an even better idea was to write a framework that could be used to implement cross-platform screensavers. The world of tools for creative coding is growing all the time, and I was positive that I could make a tool based on webtools to run screensavers on Windows, OSX, and Linux.
I looked into a few different solutions that I thought might do the trick. There's some ancient documentation about using Java to run a screensaver – if I could get that to work, then it might be possible to make screensavers with Processing. I looked at openFrameworks, and cinder, but both of those are advanced tools and the barrier to entry was way too high.
After some research, I discovered Electron – a tool for building cross-platform apps in HTML/JS. I could use Electron to build a simple tool which would let the user pick a screensaver. Then, I'd write a second Electron app to load an HTML page as the screensaver.
spending the day fiddling with writing a cross-platform screensaver app in js— colin mitchell 🏴 (@muffinista) July 20, 2015
At this point, I fell into yet another rabbit hole. Making a screensaver on Windows is easy – you can literally take any EXE file, rename it to a SCR file, and it basically works as a screensaver. Linux is just about as easy. I knew that on either playform I wouldn't have any problem making a simple program in Electron to load an HTML page and display it as a screensaver.
Unfortunately, making a screensaver on OSX is a lot more involved. You need to write a custom program that gets hooked into the operating system and is responsible for updating the screen frame by frame while the screensaver runs. This wasn't going to fit well with my idea of just loading a web page and displaying the results.
I spent a couple of months experimenting with different ways of getting an OSX screensaver to work. Most of that time was spent trying to embed Chromium into an OSX screensaver. This was time-consuming, involved me learning a bit of Objective-C, and never got anywhere.
Eventually I decided that I was being ridiculous. I didn't actually need to run a screensaver by the officially sanctioned route. I could simply write an Electron app that would do everything – it could have a preferences system for picking a screensaver and determining when/how it ran, and it would monitor the computers idle time, and trigger the screensaver when needed.
So I wrote the whole thing in Electron, and had a fairly viable system after a month or two of random nights and weekends. This was my first real project using node, and I haven't shipped many desktop apps either, so there was a learning curve there.
A lot of the problems and issues I worked on are likely the same issues that teams of programmers at Apple and Microsoft have also faced – what to do when there is an app in full screen? Should a screensaver run when a laptop isn't plugged in? How to manage multiple monitors? And so on, and so on. I spent a long time wondering about problems like this and coming up with the best solutions I could. Everything in Electron is a web page, and I spent lots of time exploring different CSS frameworks to use to try and get the perfect look. I experimented with different methods of doing things. I wrote code to notify the user when a new update is available. I refactored, rewrote, etc, etc.
One thing that took a long time, but was totally worthwhile, was adding the ability to grab an image of the desktop and send it to the screensaver, so you can have screensavers that glitch the screen, blur it, or add all sorts of other effects. But getting this to work cross-platform was a decent amount of work.
I had one main task I wanted to accomplish before calling this project done – I wanted to make it easier for other people to add screensavers to the project. Before Dawn has a 'Create Screensaver' button which you can use to create a template for a screensaver. There's also a tool to update the data needed to include a saver in Before Dawn, and a pretty simple live preview tool – it's a window that will refresh a preview of the screensaver any time you edit your code.
I also made a preview website where you can get an idea of how the screensavers actually perform.
Anyway, that's about it. Please check out the project!