How to kind of turn Firefox into a screensaver

How to do things, solutions, recipes, tutorials
Post Reply
Message
Author
User avatar
souleau
Posts: 148
Joined: Sun 23 Oct 2016, 15:24

How to kind of turn Firefox into a screensaver

#1 Post by souleau »

This started with me thinking what a nice idea it would be to have a screensaver with animated scalable vector graphics. Because you can animate svg's, and so it seemed they were ultimately suitable for something like that.
The problem though, as you may or may not know, is that the svg parser we use in Linux, which is librsvg, does not support animation. And that's a pity, because imagine the possibilities.
I suppose for some, stuff like animated icons, wallpapers and such need to be chucked on the big horror hill of bloat, but you know, others like some playful graphical elements in their gui.

However, the Firefox browser uses an svg parser which DOES support animated svg, so I figured that perhaps it would be a nice idea to set up the Firefox browser as a screensaver. And this became my project.

Now, understand, I know nothing about scripting, so what I did mostly is look on the Internet for people who do know, and were willing to demonstrate and make available the things I was looking for.

So what did I want?

1. A script that would open my Firefox browser, put it in full screen, and then load what I wanted to load.
2. A script in my Startup folder that would track the computers idle time (time passed without any activity), and then after a given amount of time give the command to run the script that opens Firefox and loads what I want.
3. An svg animation that runs in Firefox indefinitely.

Because this is more a proof of concept than anything else, I kind of did it quick and dirty. Those of you that are more actively involved in system modification and maintenance would undoubtably have done it more cleanly, but I just wanted to make it work.

So, first things first. A script to open the browser and load something specific.

I created a file in the root called simplescreensaver, and it only contained one line:

Code: Select all

#!/bin/sh

firefox "my-documents/screensaver01.html"
There. Now, if I would give my script the proper permissions, I could click on it in ROX, or call it in terminal, and it would open Firefox, and Firefox would load a page in the folder my-documents called screensaver01.html.

What I want though, is not only that it loads the page, but I also want Firefox to go into fullscreen mode.
You might be able to achieve that by changing the configuration of Firefox so that it would always open in fullscreen mode, but of course I don't want that. I only want it to do that when it kicks in as a screensaver.
To normally get Firefox to go to real fullscreen, you need to have your mouse in the browser window and press F11 on your keyboard. So what I need is something that tells my system this is happening, and what I discovered is that something like that exists, and that it is called xdotool. Xdotool tells your system that certain keys are pressed or your mouse behaves a certain way. Very handy.
So I found a Ubuntu repository which had a version for me (Puppy Precise), installed it, and after some experimenting, my script looked like this:

Code: Select all

#!/bin/sh

	firefox -fullscreen & sleep 4
	xdotool mousemove 720 450
	xdotool click 1
	xdotool key F11
	firefox "my-documents/screensaver01.html"
The first line puts Firefox in a normal screenwide mode and then pauses 4 miliseconds. The second line lets xdotool tell the system to move the mouse cursor to a designated spot on my screen. Since my monitor size is 1400x900, I chose for the spot to be exactly in the middle, making sure it was now on the page area of my browser. The third line lets xdotool tell the system that the mouse has clicked its left button once, so that I am certain that the focus is now on the browser window. And then line number 4 lets xdotool tell the system that the F11 key is being pressed, so that Firefox now goes into fullscreen mode.

Now all we have to do is make a script that will activate itself at startup, monitor the time passed without any activity, and execute our simplescreensaver script after a given time period.

If you want a script to automatically be excuted at startup, you can place it in a folder in root, which is conveniently named Startup.
So I created a script called screensavestart and placed it in the Startup folder. The script had to have some way of monitoring time passed without activity, and for this purpose, I discovered, another utility exists, which is called xprintidle. So I looked for the correct package online and installed it.
Since I had no idea how to cook up a script that would do what I wanted, I just looked on the Internet until I found something that I could use.
This is the little script that does the trick:

Code: Select all

#!/bin/bash

#Check if X is idle. Timer set to 5 minutes.

export DISPLAY=:0

idletime=0

while [ $idletime -le 300000 ]
do
echo "Idle Time is: $idletime milliseconds"
sleep 1
idletime=$(xprintidle)
done

/root/simplescreensaver

In this case the 300000 stands for miliseconds, which is 5 minutes. Do not forget to give this script the proper permissions also.

You might think this would be enough, but then you would be forgetting something very important. The thing is, you see, that the screensavestart script will keep on running and tracking idle time even while the screensaver is active. And so it will also ask the simplescreensaver script to execute again after a certain amount of time, and then, of course, another instance of Firefox running your screensaver would start, and this would repeat itself over and over until your system completely freezes.

And we do not want that.

So what we need is something that tells your simplescreensaver script that Firefox is already running. We do that with the grep command. That also means we have to make a conditional statement in our simplescreensaver script.

So, going back to the simplescreensaver script in root, these are the changes made:

Code: Select all

#!/bin/sh
SERVICE='firefox'
 
if ps ax | grep -v grep | grep $SERVICE > /dev/null
then
    echo "eq 0 - firefox running - do nothing"
else
	firefox -fullscreen & sleep 4
	xdotool mousemove 720 450
	xdotool click 1
	xdotool key F11
	firefox "my-documents/screensaver01.html"
fi
What it says is; first look if there is a process running called firefox, if there is, do nothing, if there isn't, do all the other stuff.

Now, of course, you could have Firefox running on your computer and you could be walking your dog or unplugging the sink or conducting an opera hoping that a screensaver would activate itself in your absence. In that case you would be unlucky.

Okay, now we want something to appear in Firefox that does something screensaver-like.
First, we make the html page in the my-documents folder, called screensaver01.html.

Here's the html code for that:

Code: Select all

<HTML>

<HEAD>

<TITLE>SVG screensaver</TITLE>
<style type="text/css">
#centered_div {width: 350px; height: 350px; position: absolute; top: 50%; left: 50%; margin-top: -175px; margin-left: -175px;}</style>
</HEAD>
<BODY BGCOLOR="#000">
<!-- HTML Code -->
<div id="centered_div">
<img src="animation.svg" />
</div>
</BODY>

</HTML>
The svg animation itself is 350px wide and 350px height. What I want, is for it to be exactly in the middle of your screen. That is what that centered_div is all about. You define its width and height in pixels, you tell it to go to the middle of your screen (top: 50%; left: 50%), but because it calculates the middle from the origin (0px, 0px), which is where the upper left corner of your svg is initially, you can only position your svg exactly in the middle if you subsequently reduce the left and upper margin with minus half the size of your svg's width and length (margin-top: -175px; margin-left: -175px;).

My animation, aptly named animation.svg, is in the same my-documents folder, and this is the code:

Code: Select all

<svg xmlns="http://www.w3.org/2000/svg" width="350" height="350">
<path d="M0 0h350v350H0z"/>
<path d="M161 0l-33-57-74-4L0 0l7 81 62 41 62-27 6-66-58-46L0 0l-41 70 25 70 66 14 43-50-20-71L0 0l-75 33-20 71 44 50 65-14 26-70L0 0l-80-17-58 46 6 66 61 27 62-41L0 0l-55-61-74 4-34 57 34 57 74 3L0 0l-9-81-62-41-61 26-6 67 58 46L0 0l40-70-26-70-65-15-44 50 20 72L0 0l73-33 20-72-43-50-66 15-25 70L0 0l79 17 58-46-6-67-62-26L7-81 0 0l54 60 74-3z" fill="#ddf" fill-rule="evenodd" stroke="#444" stroke-width="5" transform="translate(175 175)">
<animateTransform attributeName="transform" attributeType="XML" begin="0s" dur="10s" type="rotate" from="0 0 0" to="36 0 0" repeatCount="indefinite" additive="sum"/>
<animateTransform attributeName="transform" attributeType="XML" type="scale" from="1" to=".05" begin="0s" dur="120s" repeatCount="indefinite" additive="sum"/>
<animate attributeName="stroke" begin="0s" dur="30s" repeatCount="indefinite" values="#fff;#000;#fff"/>
<animate attributeName="fill" begin="0s" dur="30s" repeatCount="indefinite" values="#000;#fff;#000"/>
</path>
</svg>
I could try and explain svg and svg animation, but I'm afraid that would make this a very long post.
Besides, it's not really important, because you could, if you prefer, make something else in your screensaver01.html page, like a css/jquery slidehow. The point is that you can now use your browser as a rudimentary screensaver.

If I really knew what I was doing, I'd make it so Firefox would unload at any renewed activity, but like I said, this is more like a proof of concept for me, plus, I'm a total dork when it comes to scripting.

User avatar
souleau
Posts: 148
Joined: Sun 23 Oct 2016, 15:24

#2 Post by souleau »

If you're in a trippy mood, here's a variant on the svg animation I did. A bit of a kaleidoscopic effect.

It can be heavy on the cpu though, at least it is on this old clunker.

So, just to be clear, you can either name this one animation.svg in your my-documents folder, or you can go into your screensaver01.html page and change animation.svg into whatever svg you will name this one.

Code: Select all

<svg xmlns="http://www.w3.org/2000/svg" width="350" height="350">
<path d="M0 0h350v350H0z"/>
<path d="M160 0l-48-65-87 22L0 49l65 63 73-32-9-80-86-25-68 68 25 86 80 9 32-73L50 0l-93 25-22 87 65 48 65-48-22-87-93-25-62 65 32 73 80-9 25-86-68-68-86 25-9 80 73 32L0 49l-25-92-87-22-48 65 48 65 87-22L0-50l-65-62-74 32 10 80 86 25 68-68-25-87-80-9-32 74 62 65 93-25 22-87-65-48-65 48 22 87L50 0l62-65-32-74-80 9-25 87 68 68 86-25 9-80-73-32L0-50l25 93 87 22z" fill="#ddf" fill-rule="evenodd" stroke="#444" stroke-width="5" transform="translate(175 175)">
<animateTransform attributeName="transform" attributeType="XML" begin="0s" dur="10s" type="rotate" from="0 0 0" to="-30 0 0" repeatCount="indefinite" additive="sum"/>
<animate attributeName="stroke" begin="0s" dur="40s" repeatCount="indefinite" values="#00ff00;#0000ff;#ff0000;#00ff00;"/>
<animate attributeName="fill" begin="0s" dur="30s" repeatCount="indefinite" values="#ff0000;#00ff00;#0000ff;#ff0000;"/>
<animate attributeName="stroke-opacity" begin="0s" dur="35s" repeatCount="indefinite" values="0;1;0;"/>
<animate attributeName="fill-opacity" begin="0s" dur="50s" repeatCount="indefinite" values="1;0;1;"/>
</path>
<path d="M161 0l-33-57-74-4L0 0l7 81 62 41 62-27 6-66-58-46L0 0l-41 70 25 70 66 14 43-50-20-71L0 0l-75 33-20 71 44 50 65-14 26-70L0 0l-80-17-58 46 6 66 61 27 62-41L0 0l-55-61-74 4-34 57 34 57 74 3L0 0l-9-81-62-41-61 26-6 67 58 46L0 0l40-70-26-70-65-15-44 50 20 72L0 0l73-33 20-72-43-50-66 15-25 70L0 0l79 17 58-46-6-67-62-26L7-81 0 0l54 60 74-3z" fill="#ddf" fill-rule="evenodd" stroke="#444" stroke-width="5" transform="translate(175 175)">
<animateTransform attributeName="transform" attributeType="XML" begin="0s" dur="10s" type="rotate" from="0 0 0" to="36 0 0" repeatCount="indefinite" additive="sum"/>
<animate attributeName="stroke" begin="0s" dur="35s" repeatCount="indefinite" values="#ff0000;#00ff00;#0000ff;#ff0000;"/>
<animate attributeName="fill" begin="0s" dur="50s" repeatCount="indefinite" values="#0000ff;#ff0000;#00ff00;#0000ff;"/>
<animate attributeName="stroke-opacity" begin="0s" dur="40s" repeatCount="indefinite" values="0;1;0;"/>
<animate attributeName="fill-opacity" begin="0s" dur="30s" repeatCount="indefinite" values="1;0;1;"/>
</path>
</svg>

User avatar
souleau
Posts: 148
Joined: Sun 23 Oct 2016, 15:24

#3 Post by souleau »

I found this wonderful webpage via boingboing.net, which uses javascript to create an interactive animation of the Hopalong fractal. It seems to be perfect for the purpose of creating a screensaver.

This is the url:

http://iacopoapps.appspot.com/hopalongwebgl/

So forget about that clunky svg animation for now, we're going to set this one up in our script.

We need to open the simplescreensaver script in root, and make the following changes:

Code: Select all

#!/bin/sh
SERVICE='firefox'
 
if ps ax | grep -v grep | grep $SERVICE > /dev/null
then
    echo "eq 0 - firefox running - do nothing"
else
	firefox -fullscreen & sleep 4
	xdotool mousemove 720 450
	xdotool click 1
	xdotool key F11
	firefox "http://iacopoapps.appspot.com/hopalongwebgl/" & sleep 4
	xdotool mousemove 360 675
fi
As you may have noticed, I have also changed the screen position of the cursor with the mousemove function after I have allowed the javascript to load in the page. This is because the hopalong visualizer uses the cursor position as camera position. And since the absolute middle is pretty much the most boring zoom angle, the new position will add to the dramatic effect.

P.S.: If you use an add-on like NoScript, you'll have to put this url on your whitelist for it to work.

Enjoy!
Last edited by souleau on Wed 14 Dec 2016, 12:45, edited 1 time in total.

User avatar
Flash
Official Dog Handler
Posts: 13071
Joined: Wed 04 May 2005, 16:04
Location: Arizona USA

#4 Post by Flash »

Well done, Souleau! One of the best-written How-tos I've seen. Thank you. :)

User avatar
souleau
Posts: 148
Joined: Sun 23 Oct 2016, 15:24

#5 Post by souleau »

Flash wrote:Well done, Souleau! One of the best-written How-tos I've seen. Thank you. :)
Thank you very much Flash!

Had to make a slight edit in the script I posted because it mentioned firefox-portable, which I use myself, instead of plain firefox.

It is as it should be now.

Post Reply