Project

General

Profile

unexist.dev

Assorted tidbits and projects

Sublets » History » Version 54

Anonymous, 10/20/2010 11:06 AM

1 54
h1. Sublets\015\012\015\012{{>toc}}\015\012\015\012[[Sublets]] are small "Ruby":http://www.ruby-lang.org scripts written in a small "DSL":http://en.wikipedia.org/wiki/Domain_Specific_Language 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 [[sublets|sublet]] is to let [[sur]] do all the dirty work, it's designed to be really easy and works in a "rubygems":http://www.rubygems.org 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<pre>\015\012sur install clock\015\012sur uninstall clock\015\012sur notes clock\015\012</pre>\015\012\015\012h3. Hard\015\012\015\012Ok, you asked for it: Point your browser to http://sur.subforge.org/ and download a [[sublets|sublet]]. Then you need to unpack the [[sublets|sublet]] - they are just tarballs. Once unpacked you will probably find three types of files:\015\012\015\012# A [[sublets|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 [[sublets|sublet]] file itself, which can be troublesome for users not that in love with "ruby":http://ruby-lang.org. In case the [[sublet]] supports the newer way (since r2148) there is a special "DSL":http://en.wikipedia.org/wiki/Domain_Specific_Language command for this:\015\012\015\012<pre>{{hide}}<code class="ruby">sublet :clock do\015\012  interval      50\015\012  format_string "%H:%S"\015\012end</code></pre>\015\012\015\012h2. Writing\015\012\015\012Starting a [[sublets|sublet]] from scratch is really easy, just create an empty [[sublets|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":http://subforge.org/rdoc/subtle/index.html 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":http://en.wikipedia.org/wiki/Inotify) or via socket\015\012\015\012The [[sublet]] data *must* be of type "String":http://www.ruby-doc.org/core/classes/String.html, everything else will be ignored.\015\012\015\012h3. Events\015\012\015\012[[Sublets]] are event driven, so there are some specific events only for [[sublets]] and it's also possible to use any existing [[Hooks|hook]].\015\012\015\012*Specific events:*\015\012\015\012| *&#58;mouse_over* | Whenever the pointer is over the [[sublet]] |\015\012| *&#58;mouse_down* | Whenever the pointer is pressed on the [[sublet]]. Can have three arguments: x, y, button. |\015\012| *&#58;mouse_out*  | Whenever the pointer leaves the [[sublet]] |\015\012| *&#58;run*        | Whenever either the interval time is expired |\015\012| *&#58;unload*     | Whenever the sublet is unloaded |\015\012| *&#58;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<pre>{{hide}}<code class="ruby">\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</code></pre>\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\012[[Sublets]] can either be configured by editing the [[sublet]] file or by a special "DSL":http://en.wikipedia.org/wiki/Domain_Specific_Language command in the main config (since r2148) of [[subtle]]. The latter done via "Subtle::Subtle#config":http://api.subforge.org/classes/Subtle/Sublet.html#M000244, this returns a "hash":http://ruby-doc.org/core/classes/Hash.html and can be used as in the following example:\015\012\015\012h4. Inside of the config\015\012\015\012<pre>{{hide}}<code class="ruby">sublet :configured do\015\012  interval    50\015\012  some_string "#00ff00"\015\012end</code></pre>\015\012\015\012h4. Inside of the sublet\015\012\015\012<pre>{{hide}}<code class="ruby">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</code></pre>\015\012\015\012h3. Customization\015\012\015\012The color of the ouput of a [[sublet|Sublets]] can be changed in this way:\015\012\015\012<pre>{{hide}}<code class="ruby">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</code></pre>\015\012\015\012There is also a way to add a "X bitmap":http://en.wikipedia.org/wiki/XBM to a [[Sublets|sublet]]:\015\012\015\012<pre>{{hide}}<code class="ruby">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</code></pre>\015\012\015\012A nice collection of this pixmap can be found "here":http://dzen.geekmode.org/dwiki/doku.php?id=dzen:icon-packs.\015\012\015\012_[[Subtle]] 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 [[sublet|sublets]] that displays the time. It should be really straight forward:\015\012\015\012<pre>{{hide}}<code class="ruby">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</code></pre>\015\012\015\012Another example for the "inotify":http://en.wikipedia.org/wiki/Inotify [[sublets|sublet]] which is also included within [[subtle]]:\015\012\015\012<pre>{{hide}}<code class="ruby">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</code></pre>\015\012\015\012The *watch* command also works with "Ruby":http://www.ruby-lang.org sockets, but be aware of blocking I/O:\015\012\015\012<pre>{{hide}}<code class="ruby">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</code></pre>\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<pre>{{hide}}<code class="ruby">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</code></pre>