<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://whijo.net" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>xscreensaver</title>
 <link>http://whijo.net/taxonomy/term/70/feed</link>
 <description>The taxonomy view with a depth of 0.</description>
 <language>en</language>
<item>
 <title>Hey Rhythmbox, go pause yourself!</title>
 <link>http://whijo.net/blog/brad/2007/07/26/hey-rhythmbox-go-pause-yourself.html</link>
 <description>&lt;p&gt;A while back &lt;a href=&quot;http://nxsy.org/blog/archives/2007/03/20/getting-amarok-to-pause-when-the-screen-locks-using-python-of-course&quot;&gt;NBM wrote a script to pause Amarokk when his screensaver turned on&lt;/a&gt;. Since I get competitive I felt I could do it better, and do it for the media player that I love, &lt;a href=&quot;http://www.gnome.org/projects/rhythmbox/&quot;&gt;Rhythmbox&lt;/a&gt;. If you are wondering what purpose this really serves, imagine you are away from your desk for a long time, you want to make sure the music is the same when you come back, and you don&#039;t want to bug any co-workers. It also serves the purpose of deepening my understanding of python, and scratches the itch of customising desktops (and feeling better than windows people). So...&lt;/p&gt;
&lt;p&gt;I started out writing a daemonisd script like the one &lt;acronym title=&quot;Neil Blakey-Milner&quot;&gt;nbm&lt;/acronym&gt; built, which listens on the d-bus (the Linux/Freedesktop inter-process messaging/control bus), and connects to Rhythmbox on the same bus to get in control. &lt;a href=&quot;http://nxsy.org/blog/archives/2007/03/20/getting-amarok-to-pause-when-the-screen-locks-using-python-of-course#comment-5167&quot;&gt;Taking his script and changing the message passing&lt;/a&gt; to point to &lt;acronym title=&quot;Rhythmbox&quot;&gt;RB&lt;/acronym&gt; instead of Amarokk was trivial (but a mission due to lack of documentation) and I threw in some improvements.&lt;/p&gt;
&lt;p&gt;Then I got itchy and figured I could write a plugin for RB and push control of the functionality to RB (where it belongs), and drop the need for a daemon script. So I opened up the artdisplay plugin for Rhythmbox (since it is a python based plugin) to get an idea of what is involved. After browsing through the plugin, and reading the &lt;a href=&quot;http://live.gnome.org/RhythmboxPlugins/WritingGuide&quot;&gt;Rhythmbox plugins writing guide&lt;/a&gt; I rolled my own.&lt;/p&gt;
&lt;p&gt;I call my plugin dbusevents because while it pauses when the screen saver is on it could be extended to support multiple events and actions (maybe you want the volume turned up louder when you first plug in your mouse so you can party). So, a Rhythmbox plugin inhabits a directory and has atleast two parts: A descriptor file, and the plugin.&lt;/p&gt;
&lt;p&gt;You can download the whole thing: &lt;a href=&quot;http://whijo.net/files/dbusevents.tar.gz&quot; title=&quot;Download: dbusevents.tar.gz (1.42 KB)&quot;&gt;dbusevents.tar.gz&lt;/a&gt;. To use it drop the extracted directory in /usr/lib/rhythmbox/plugins/&lt;/p&gt;
&lt;p&gt;My descriptor file looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[RB Plugin]
Loader=python
Module=dbusevents
IAge=1
Name=DBUS Events
Name[en_GB]=DBUS Events
Description=Connects Rhythmbox actions to DBUS events (for e.g. pausing when the screensaver is on)
Description[en_GB]=Connects Rhythmbox actions to DBUS events (for e.g. pausing when the screensaver is on)
Authors=Bradley Whittington 
Copyright=Copyright © 2007 Bradley Whittington
Website=http://www.rhythmbox.org
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pretty straightforward stuff eh? The net result is:&lt;br /&gt;
&lt;span class=&quot;inline&quot;&gt;&lt;a href=&quot;http://whijo.net/files/rhythmbox-dbus-config.png&quot; class=&quot;inline-image-link&quot; title=&quot;View: rhythmbox-dbus-config.png&quot; rel=&quot;lightbox[gp_inline]&quot;&gt;&lt;img src=&quot;http://whijo.net/files/imagecache/inline_resize/files/rhythmbox-dbus-config.png&quot; alt=&quot;rhythmbox-dbus-config.png&quot; title=&quot;rhythmbox-dbus-config.png&quot;  class=&quot;inline&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The meat of the plugin is contained in dbusevents/__init__.py which implements a Rhythmbox plugin, which means it inherits from rb.plugin (import rb), implements at least __init__, activate, and deactivate.&lt;/p&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class DbusEventsPlugin (rb.Plugin):
#Initialisation 
        def __init__ (self):
                rb.Plugin.__init__ (self)

        def activate (self, shell):
                self.shell = shell
                self.rb = shell.get_player ()
                self.session_bus = dbus.SessionBus()
                self.load_events()
                self.connect_events()

        def deactivate (self, shell):
                self.disconnect_events()
                self.save_events()
                self.shell = None
                self.rb = None
                self.session_bus = None
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;
When my plugin is told to activate it assigns self.rb to an instance of the Rhythmbox shell, makes a connection to the D-BUS session bus, and assigns the instance to self.session_bus, then it calls load_events (which could load events and actions from a config file), and finally connect_events which tells the session_bus which functions to call when certain events happen. The deactivate function does everything, in reverse ;). Ultimately I would like to make a configuration dialogue which allows you to have your custom event-action set up, but I havent found anything more beyond pausing when the screensaver is on.&lt;/p&gt;
&lt;p&gt;The magic in connect_events and disconnect_events is pretty basic, at the moment it walks a dictionary with relevant information:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        events = {
                        &#039;Screensaver Play/Pause&#039;:{
                                &#039;__doc__&#039;:&#039;Pauses Rhythmbox when the Screensaver is running&#039;,
                                &#039;handler&#039;:&#039;playPause&#039;,
                                &#039;signal&#039;:(&#039;SessionIdleChanged&#039;,&#039;org.gnome.ScreenSaver&#039;),
                                &#039;enabled&#039;:True,
                        }
                }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The functions use self.session_bus.add_signal_receiver and self.session_bus.remove_signal_receiver to attach events to actions. I have only defined a PlayPause function at the moment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        def playPause(self,state):
                if not state:
                        if self.wasplaying:
                                self.rb.play()
                else:
                        self.wasplaying = self.rb.get_playing()
                        self.rb.pause()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which checks if it is playing when the screensaver is turned on, and pauses if it is, and unpauses when the screensaver turns off, if it was paused when the screensaver went on.&lt;/p&gt;
&lt;p&gt;I would appreciate feedback, so drop me a comment if you have any!&lt;/p&gt;
</description>
 <comments>http://whijo.net/blog/brad/2007/07/26/hey-rhythmbox-go-pause-yourself.html#comments</comments>
 <category domain="http://whijo.net/geek-tags/d-bus">d-bus</category>
 <category domain="http://whijo.net/geek-tags/gnome-screensaver">gnome-screensaver</category>
 <category domain="http://whijo.net/geek-tags/linux">linux</category>
 <category domain="http://whijo.net/geek-tags/python">python</category>
 <category domain="http://whijo.net/geek-tags/rhythmbox">rhythmbox</category>
 <category domain="http://whijo.net/geek-tags/xscreensaver">xscreensaver</category>
 <enclosure url="http://whijo.net/files/dbusevents.tar.gz" length="1453" type="application/x-gzip" />
 <pubDate>Thu, 26 Jul 2007 16:41:49 +0200</pubDate>
 <dc:creator>brad</dc:creator>
 <guid isPermaLink="false">109 at http://whijo.net</guid>
</item>
</channel>
</rss>
