PHP D-Bus Screensaver

Howto run your script when the ScreenSaver starts
OR
When the Desktop has been Idle for a while ?

Well here is how to grasp the basics and have a little fun. Its also very useful to be able to kick off a script when the Desktop is idle. In my case I want to encode a tv epsiode into an mpeg – but not while I am using the computer. The point is this, it is smart to do some jobs when the computer has been either idle for a while, or the screensaver has kicked in.

Note you can use this to find out how idle the computer is, and bypass actually running the screensaver, or you could do something after the screensaver has been running for a long time period.

To see all the methods and properties of ScreenSaver, got to a konsole and type in:

qdbusviewer &

Without getting side tracked and exploring everything running on your Desktop, concentrate on finding :

org.freedesktop.ScreenSaver

This gives you a nice and friendly method to explore the ScreenSaver methods and properties.

Now the next job is to get it all into a text file, so we can copy paste stuff directly… The method and property names are really long text strings, and its case sensitive. If your not dyslexic, you will be after working with D-Bus. 🙂

Type in a console :

qdbus org.freedesktop.ScreenSaver /ScreenSaver > D_Bus_ScreenSaver.txt

Note, I am using the generic cross platform D-Bus ScreenSaver. If you are using another Desktop, you will probably see two listed, one specific to your Desktop such as KDE and one generic one… We will use the generic as best or sane practice.

Now we got a text file, from which we can copy and paste. This saves a lot of time and effort and farting around is avoided. Here is the results I got…

signal void org.freedesktop.ScreenSaver.ActiveChanged(bool)
method bool org.freedesktop.ScreenSaver.GetActive()
method uint org.freedesktop.ScreenSaver.GetActiveTime()
method uint org.freedesktop.ScreenSaver.GetSessionIdleTime()
method uint org.freedesktop.ScreenSaver.Inhibit(QString application_name, QString reason_for_inhibit)
method void org.freedesktop.ScreenSaver.Lock()
method bool org.freedesktop.ScreenSaver.SetActive(bool e)
method void org.freedesktop.ScreenSaver.SimulateUserActivity()
method uint org.freedesktop.ScreenSaver.Throttle(QString application_name, QString reason_for_inhibit)
method void org.freedesktop.ScreenSaver.UnInhibit(uint cookie)
method void org.freedesktop.ScreenSaver.UnThrottle(uint cookie)
method void org.kde.screensaver.configure()
method void org.kde.screensaver.saverLockReady()
method void org.kde.screensaver.setupPlasma()
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()

Phew… what a big pile of spaghetti huh ?

Well do not panic, I know it looks uber nasty complex , but it is really simple. Its the keeping it simple that makes it so long winded. But, since we are going to Copy and Paste, no need to panic.

Before we go any futher, please check you actaully got screensaver configured. This might sound daft, but if the screensaver is not configured to Automaticaly Start the script is not going to work. You might well have turned it off ages ago when it got annoying or pesky. If you do find it annoying set it kick in after an insane amount of time.. Setting it to 1440 minutes means it would have to be idle for 12 hours before the screensaver kicked in.

Ok, lets give it a whirl from the konsole as quick sanity check

qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive 1

That should have kicked in the ScreenSaver.

Lets break it down…

The first bit gets us to qdbus, the command line method of talking to D-Bus.

The second part gets us to the ScreenSaver “org.freedesktop.ScreenSaver” , but not quiet as at this point we could fork down to other stuff we are not interested in…

We fork down to “/ScreenSaver” to get at its methods and properties.

The last part we finally invoke the method “org.freedesktop.ScreenSaver.SetActive 1”. Of course setting it to false would stop the screensaver… something you might want to do inside or after you have run your script.

void set_Active( boolean )

Lets warp it all up in a PHP function, you’ll probably want to wrap it all in a Class latter, that way you can bolt on the ScreenSaver to anything you create at a latter date.

function set_Active( $switch ) {
  exec("qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive $switch",$out,$ret);
}

Of course you could make it way more elaborate, and you could check that it has been passed a boolean, and other kitchen sink validity and sanity checks. You should in theory check that it did not return an error and so on…

int  = get_Session_Idle_Time ( )

Here is another function, this time to find out how long, the computer has been idle, which is really useful. By using this method, you can decide to launch before or after the screensaver has kicked in… It will return an answer in seconds.

function get_Session_Idle_Time() {
    exec("qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.GetSessionIdleTime", $out,$ret );
    #echo "\$out[0]=".$out[0]."\n";
    return $out[0];
  }

You should note that your script can loop a lot faster than you can get back a new, different, updated answer from D-Bus.

$stop=time()+60;
while() {
  usleep(1000000); // sleep 1 second
  echo get_Session_Idle_Time()."\n";
}

Now if you run that code snippet, you can see what really happens. You will be in for a surprise.

boolean = is_ScreenSaver_On ( )

This time lets find out if the ScreenSaver is running. Its a yes no question that a script will want to know.

function is_ScreenSaver_On() {
  exec( 'qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.GetActive ',$out,$ret );
  if( $out[0]==='false' ) {
    #echo "Screen Save is OFF\n";
    return False;
  }
  #echo "Screen Save is ON\n";
  return True;
}

At this point you should have grasped how to write tiny wrapper functions to access the ScreenSaver from PHP.

How you stick it all together and what you do with it are up to you, I will only caution you to check the screen saver has been running for a little while before starting the real code… Give the user an opportunity to grab the mouse and give it a wriggle.. Otherwise your wonderful script could become an annoyance.

Anyway, now that you have seen how easy it can be to do things with D-Bus, you might like to poke around and play with Konversation and get your scripts to use IRC. Another fun thing is to play with Konqueror, but it is a big App and quite tricky to figure out. Another fun thing is poke around with Amarok.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s