Awesome WM widget tooltip example

Posted by jason on Oct. 22, 2011, 10:58 a.m.
Tags: arch awesome config linux widgets

I thought I'd post a simple example of how to set up a custom tooltip for a widget in Awesome.

This example will add an icon to a wibox, and when the user hovers over it, that machine's internal and external IP addresses will be shown. To do so, I'll write a bash script that outputs this information in plain text, like so:

Internal: 192.168.0.100
External: 66.101.33.134

I'll set up Awesome to run my script every hour and to update the tooltip accordingly.

Step 1: Generate text for the tooltip

Here's a simple bash script that outputs the information I want:

#!/bin/sh

WGET=$(which wget)
WGET_OPTS="-O - -q"
URL="http://automation.whatismyip.com/n09230945.asp"

IFCONFIG=$(which ifconfig)
AWK=$(which awk)
NIC="eth0"

EXTIP=`$WGET $URL $WGET_OPTS`
INTIP=`$IFCONFIG $NIC | $AWK '{ if (NR == 2) { print $2 }}'`

echo "Internal: $INTIP"
echo "External: $EXTIP"
exit 0

Make sure to note where you save this file, and don't forget to chmod +x it.

Step 2: Call the bash script from rc.lua

Now that you've written a script that outputs some useful plain text, you need to access that text from Awesome's rc.lua file (mine is in ~/.config/awesome/). Write a function that calls the script and returns the output. Put this code somewhere after the line that says "-- {{{ Wibox":

-- ips widget: show internal and external ips as a tooltip on
-- an icon.

-- function to call bash script and return its output.
function get_ips()
    local fd = io.popen("/home/jason/bin/get_ips")
    local str = fd:read("*all")
    return str 
end

Step 3: Create the widget

Continuing from Step 2, add this code after your get_ips() function, which creates a simple "imagebox" widget with the icon of your choice:

-- Set up an icon
ipsimg = widget({ type = "imagebox" })
ipsimg.image = image("/home/jason/.config/awesome/network.png")

Step 4: Create the tooltip

Next, create the tooltip, link it to the imagebox, and initialize its text:

-- Set up the tooltip, initializing to the output of get_ips()
ips_t = awful.tooltip({ objects = { ipsimg},})
ips_t:set_text(get_ips())

Step 5: Set up a timer to periodically refresh (optional)

If you have an ADSL connection, you might want to update the IP information every hour or so, in case it changes. Awesome has a timer API that you can use for this purpose. Just add this code:

-- Set up a timer to refresh every hour. Useful for ADSL connections.
mytimer = timer({ timeout = 3600 })
mytimer:add_signal("timeout", function () ips_t:set_text(get_ips()) end)
mytimer:start()

Step 6: Add the widget to the wibox

Finally, you need to add your widget to the wibox so that it shows up. To do so, add "ipsimg" to the "mywibox[s].widgets" array in the rc.lua file. Here's what mine looks like:

    mywibox[s].widgets = {
        {
            mylauncher,
            mytaglist[s],
            mypromptbox[s],
            layout = awful.widget.layout.horizontal.leftright
        },
        mylayoutbox[s],

        -- Begin custom widgets
        ipsimg,
        -- End custom widgets

        s == 1 and mysystray or nil,
        mytasklist[s],
        layout = awful.widget.layout.horizontal.rightleft
    }

That's it! Now, you can write any bash script that outputs any text, and you'll have that text in your systray via an icon and tooltip. The world is your oyster!

Aside: I quickly tried to add a "notify-send" command in my get_ips bash script, just to see if it would show up, but when I reloaded Awesome, everything was frozen. I'm not sure why this happened, and I'm too tired to wrestle with it right now.


0 comments