Sublets » History » Version 54
« Previous -
Version 54/66
(diff) -
Next » -
Current version
Anonymous, 10/20/2010 11:06 AM
Sublets\015\012\015\012{{>toc}}\015\012\015\012Sublets are small Ruby scripts written in a small DSL that can provide things like system information for the panel. They are well included in the main loop of subtle and can be used in various ways. \015\012\015\012h2. Installation\015\012\015\012h3. Easy\015\012\015\012The easiest way to install a sublet is to let sur do all the dirty work, it's designed to be really easy and works in a rubygems like fashion and since r2138 bundled with subtle.\015\012\015\012Generally sur is the subtle user repository for user contributed sublets, everyone can submit sublets via sur.\015\012\015\012\015\012sur install clock\015\012sur uninstall clock\015\012sur notes clock\015\012
\015\012\015\012h3. Hard\015\012\015\012Ok, you asked for it: Point your browser to http://sur.subforge.org/ and download a sublet. Then you need to unpack the sublet - they are just tarballs. Once unpacked you will probably find three types of files:\015\012\015\012# A sublet file (.rb) [$XDG_DATA_HOME/subtle/sublets
]\015\012# A specification file (.spec) [$XDG_DATA_HOME/subtle/specifications
]\015\012# Zero or more icons (.xbm) [$XDG_DATA_HOME/subtle/icons
]\015\012\015\012The files need to be installed in the appropriate folders in $XDG_DATA_HOME/subtle
and after a reload of either the configor the sublets you are done.\015\012\015\012h2. Configuration\015\012\015\012Many sublets can be configured by editing the sublet file itself, which can be troublesome for users not that in love with ruby. In case the sublet supports the newer way (since r2148) there is a special DSL command for this:\015\012\015\012{{hide}}sublet :clock do\015\012 interval 50\015\012 format_string "%H:%S"\015\012end
\015\012\015\012h2. Writing\015\012\015\012Starting a sublet from scratch is really easy, just create an empty sublet either with sur like sur template foo
or with any editor of your choice. A sublet has some base functions and can access subtle itself via subtlext. A compending list of the classes with it's functionality can be found in rdoc and informations about the available unit tests in the hacking section.\015\012\015\012h3. Types\015\012\015\012Generally there are two different types of Sublets:\015\012\015\012* sublets that are updated by given interval in seconds (default 60s)\015\012* sublets that are updated when a file is modified (via inotify) or via socket\015\012\015\012The sublet data must be of type String, everything else will be ignored.\015\012\015\012h3. Events\015\012\015\012Sublets are event driven, so there are some specific events only for sublets and it's also possible to use any existing hook.\015\012\015\012*Specific events:*\015\012\015\012| :mouse_over | Whenever the pointer is over the sublet |\015\012| :mouse_down | Whenever the pointer is pressed on the sublet. Can have three arguments: x, y, button. |\015\012| :mouse_out | Whenever the pointer leaves the sublet |\015\012| :run | Whenever either the interval time is expired |\015\012| :unload | Whenever the sublet is unloaded |\015\012| :watch | Whenever the watched file is modified/socket has data ready |\015\012\015\012h3. Grabs\015\012\015\012Since r2204 sublets can use grabs in a similar way as in the main config. \015\012\015\012{{hide}}\015\012configure :grabby do |s|\015\012 s.interval = 5\015\012end\015\012\015\012grab "A-b" do |s, c|\015\012 puts "sublet name: %s" % [ s.name ]\015\012 puts "pressed on : %s" % [ c.name ]\015\012end\015\012
\015\012\015\012_Please note that there is no checking if the newly created grab already exists, last one wins._\015\012\015\012h3. Configuration\015\012\015\012Sublets can either be configured by editing the sublet file or by a special DSL command in the main config (since r2148) of subtle. The latter done via Subtle::Subtle#config, this returns a hash and can be used as in the following example:\015\012\015\012h4. Inside of the config\015\012\015\012{{hide}}sublet :configured do\015\012 interval 50\015\012 some_string "#00ff00"\015\012end
\015\012\015\012h4. Inside of the sublet\015\012\015\012{{hide}}configure :configured do |s|\015\012 s.interval = s.config[:interval] || 30\015\012 s.some_string = s.config[:some_string] || "default"\015\012\015\012 # Works with colors too\015\012 s.red = Subtlext::Color.new(s.config[:red] || "#ff0000")\015\012end\015\012\015\012on :run do\015\012 s.data = s.red + s.some_string\015\012end
\015\012\015\012h3. Customization\015\012\015\012The color of the ouput of a Sublets can be changed in this way:\015\012\015\012{{hide}}configure :colorful do |s|\015\012 s.red = Subtlext::Color.new("#ff0000")\015\012 s.green = Subtlext::Color.new("#00ff00")\015\012 s.blue = Subtlext::Color.new("#0000ff")\015\012 s.background = "#303030"\015\012end\015\012\015\012on :run do\015\012 s.data = s.red + "su" + s.green + "bt" + s.blue + "le"\015\012end
\015\012\015\012There is also a way to add a X bitmap to a sublet:\015\012\015\012{{hide}}configure :iconized do |s|\015\012 s.icon = Subtlext::Icon.new("/usr/share/icons/subtle.xbm")\015\012end\015\012\015\012on :run do |s|\015\012 s.data = @icon + "subtle"\015\012end
\015\012\015\012A nice collection of this pixmap can be found Subtle" class="external">here</a> will add a padding of 3px left and right of the pixmap, so keep that in mind when using the click hooks._\015\012\015\012h3. Examples\015\012\015\012Below is the code of a shipped sublets that displays the time. It should be really straight forward:\015\012\015\012{{hide}}configure :clock do |s|\015\012 s.interval = 60 #< Set interval time\015\012end\015\012\015\012on :run do |s|\015\012 s.data = Time.now.strftime("%d%m%y%H%M") #< Set data\015\012end
\015\012\015\012Another example for the inotify sublet which is also included within subtle:\015\012\015\012{{hide}}configure :notify do |s|\015\012 s.file = "/tmp/watch"\015\012 s.watch(s.file)\015\012end\015\012\015\012on :run do\015\012 begin\015\012 self.data = IO.readlines(@file).first.chop #< Read data and strip\015\012 rescue => err #< Catch error\015\012 puts err\015\012 self.data = "subtle"\015\012 end\015\012end
\015\012\015\012The watch command also works with Ruby sockets, but be aware of blocking I/O:\015\012\015\012{{hide}}configure :socket do |s|\015\012 s.socket = TCPSocket.open("localhost", 6600)\015\012 s.watch(s.socket)\015\012end\015\012\015\012on :watch do |s|\015\012 begin\015\012 s.data = s.socket.readline.chop #< Read data and strip\015\012 rescue => err #< Catch error\015\012 puts err\015\012 s.data = "subtle"\015\012 end\015\012end\015\012\015\012on :run do |s|\015\012 # Do nothing\015\012end
\015\012\015\012_Subtle will automatically set sockets to O_NONBLOCK._\015\012\015\012And finally an example with a click callback:\015\012\015\012{{hide}}configure :click do |s|\015\012 s.interval = 999 #< Do nothing\015\012end\015\012\015\012on :mouse_down do |s, x, y, button|\015\012 Subtlext::Client["xterm"].raise\015\012 puts x, y, button\015\012end\015\012\015\012on :run do |s|\015\012 # Do nothing here\015\012end
¶
sublet :clock do\015\012 interval 50\015\012 format_string "%H:%S"\015\012end
\015\012configure :grabby do |s|\015\012 s.interval = 5\015\012end\015\012\015\012grab "A-b" do |s, c|\015\012 puts "sublet name: %s" % [ s.name ]\015\012 puts "pressed on : %s" % [ c.name ]\015\012end\015\012
sublet :configured do\015\012 interval 50\015\012 some_string "#00ff00"\015\012end
configure :configured do |s|\015\012 s.interval = s.config[:interval] || 30\015\012 s.some_string = s.config[:some_string] || "default"\015\012\015\012 # Works with colors too\015\012 s.red = Subtlext::Color.new(s.config[:red] || "#ff0000")\015\012end\015\012\015\012on :run do\015\012 s.data = s.red + s.some_string\015\012end
configure :colorful do |s|\015\012 s.red = Subtlext::Color.new("#ff0000")\015\012 s.green = Subtlext::Color.new("#00ff00")\015\012 s.blue = Subtlext::Color.new("#0000ff")\015\012 s.background = "#303030"\015\012end\015\012\015\012on :run do\015\012 s.data = s.red + "su" + s.green + "bt" + s.blue + "le"\015\012end
configure :iconized do |s|\015\012 s.icon = Subtlext::Icon.new("/usr/share/icons/subtle.xbm")\015\012end\015\012\015\012on :run do |s|\015\012 s.data = @icon + "subtle"\015\012end
configure :clock do |s|\015\012 s.interval = 60 #< Set interval time\015\012end\015\012\015\012on :run do |s|\015\012 s.data = Time.now.strftime("%d%m%y%H%M") #< Set data\015\012end
configure :notify do |s|\015\012 s.file = "/tmp/watch"\015\012 s.watch(s.file)\015\012end\015\012\015\012on :run do\015\012 begin\015\012 self.data = IO.readlines(@file).first.chop #< Read data and strip\015\012 rescue => err #< Catch error\015\012 puts err\015\012 self.data = "subtle"\015\012 end\015\012end
configure :socket do |s|\015\012 s.socket = TCPSocket.open("localhost", 6600)\015\012 s.watch(s.socket)\015\012end\015\012\015\012on :watch do |s|\015\012 begin\015\012 s.data = s.socket.readline.chop #< Read data and strip\015\012 rescue => err #< Catch error\015\012 puts err\015\012 s.data = "subtle"\015\012 end\015\012end\015\012\015\012on :run do |s|\015\012 # Do nothing\015\012end
configure :click do |s|\015\012 s.interval = 999 #< Do nothing\015\012end\015\012\015\012on :mouse_down do |s, x, y, button|\015\012 Subtlext::Client["xterm"].raise\015\012 puts x, y, button\015\012end\015\012\015\012on :run do |s|\015\012 # Do nothing here\015\012end