HOWTO: write an awesome 3 configuration file

url:http://ubuntuforums.org/showthread.php?t=879059

This howto aims to cover the basics of writing an awesome 3 configuration file in simple lua code, based on the example rc file. IT DOES NOT COVER INSTALLING, as awesome 3 is still in development (the rc has only just been released), and I'm running archlinux atm. When awesome 3 has been released, and I've set up my ubuntu machine (I need one for some work), I'll redo my old awesome howto to cover installing awesome 3.

This guide also assumes some knowledge of previous awesome versions. It is in essence the few changes I made to convert my old awesomerc to the new lua syntax.

Some info on this guide's syntax: 1. Bold is generally important, or the start of a new step. 2. Italic is code outside a "code" block. 3. Blocked code is either terminal commands, or an extended rc file section.

Contents 1. Set up 2. Open the rc file 3. Variables 4. "Floatings" 5. Appearance 6. Tags 7. Iconboxes 8. Widgets 9. Statusbars and showing widgets 10. Keybindings 11. Getting programs to open where you want them 12. Links

THE GUIDE 1. Firstly, make sure you have wicked installed. This is what we will be using for some of the widgets you may currently use. If you use conky-cli for all your widgets, don't worry about this. I don't, and so I needed wicked.

Start out by copying the example file to your home directory. On my system this was achieved with:

cd ~
mkdir -p .config/awesome
cp /etc/xdg/awesome/rc.lua .config/awesome/rc.lua

This cd's to the home directory, creates the hidden config directory, and copies the example file.

2. Open this file with your favourite editor, however you like. The first thing to do is to include the wicked library right at the top. Add require("wicked") to the section at the top, under awful and tabulous.

  1. Now add some variables to make things easier. Under "variable definitions" I added:

    terminal = "urxvt"
    browser = "firefox3"
    colorlight = "#4b7885"
    colordark = "#223b56"
    

In the case of terminal, it was changed from xterm. The colours are simply how I do my themes - a light colour and a dark colour on a black background, with a cool wallpaper. If you want more/less colours, or no variables for the here at all, that's cool.

  1. The next thing to note is the floatings section. Programs added here are launched (generally, although at time of writing gedit is coming up tiled. hmmm.) floating on all tags. Things you want to appear on top of terminals/browser windows/etc on the tag you're working on are good things to add, just like the 2 examples mplayer and pinentry. I added gedit, and only that.

  2. The Color and Appearance settings are what used to be the style section in the old rc file. Adjust as appropriate.

  3. Tags is the next section. This is very important. If you read through this section in the rc file, you'll see that by default awesome gets the number of attached monitors (screens), and adds 9 tags to them. I changed this in my file to what I used to have in awesome 2.3 - 4 tags with names:

    term = tag({ name = 'term', layout = 'tile' })
    term.screen = 1
    term.selected = true
    net = tag({ name = 'net', layout = 'max' })
    net.screen = 1
    main = tag({ name = 'main', layout = 'max' })
    main.screen = 1
    float = tag({ name = 'float', layout = 'floating' })
    float.screen = 1
    

These are written in the form:

internalname = tag ({ name = "displayedname", layout = "layout" })

Where internalname is the name for the tag when referenced in the rc file, and displayedname is the name shown on the screen. Layout is one of the layouts described in the section near the top of the file, just as in 2.3. With all of the tags you must add them to a screen (term.screen = 1), and you must select one to start on. You should also note that screens start from 1, not 0.

  1. Iconboxes are accomplished as follows:

    myiconbox = widget({ type = "textbox", name = "myiconbox", align = "left" })
    myiconbox.text = "<bg image=\"/full/path/to/icon\" resize=\"true\"/>"
    

8. You can leave the next few sections as they are, with the exception of maybe removing the awesome version textbox. We'll create our own. These go like this:

internalname = widget ({ type = "textbox", name = "displayedname", align = "left/right" })
internalname.text = "some text"

This is where wicked comes in - it has some very useful built-in status functions designed for awesome. The ones I use are:

wicked.register(rootbox, 'fs', '  ${/ usep}%  ', 30)
wicked.register(homebox, 'fs', '  ${/home usep}%  ', 30)
wicked.register(mpdbox, 'mpd', '  $1  ')
wicked.register(clockbox, 'date', '  %H:%M  ')
wicked.register(linkbox, 'net', '  ${wlan0 rx} // ${wlan0 tx}  ')

These give me the used disk space as a percentage, the current mpd state, the time, and the up/down speeds of my network connection. The other boxes I have run os functions to display things like battery status and connected network. These use wicked's built in capability to call os functions, and allow me to get rid of the status script that I used in 2.3. The code for this is as follows:

wicked.register(internalname, 'function', function (widget, args)
   local filedescriptor = io.popen('os commmand')
   local value = filedescriptor:read()
   filedescriptor:close()
   return value
end, timebetweenupdates)

For more info on wicked have a look here. See my attached rc file at the end for the 2 I use.

  1. Once we've created our widgets, we need to create a statusbar or two, and add the widgets to them. I use 2; a top one for tags, widgets, and other things; and a bottom one for the tasklist and systemtray. If you look at the example rc file which you copied, it probably does something in a for loop to add a statusbar to each screen. I only use 1 monitor, so I changed it to this:

    mystatusbartop = statusbar({ position = "top", name = "statustop", fg = fg_normal, bg = bg_normal })
    mystatusbarbtm = statusbar({ position = "bottom", name = "statusbottom", fg = fg_normal, bg = bg_normal })
    

I then added all my widgets with the simple code (for each one):

mystatusbarname:widget_add(internalname)

Don't forget to put the statusbar onto a screen with mystatusbarname.screen = 1. Also don't forget that the tasklist, taglist, systemtray are all widgets, and needed to be added as such.

  1. KEYBINDINGS. Now the fun part you've all been waiting for. Keybindings in awesome 3 are nice and easy once you know how. Because you (possibly/probably) changed the tag names, you'll need to redo the mod4 + number hotkeys. These are the ones that let you use the numbers to refer to tags, allowing you to view/toggle/move clients and tags. There are 4 commands relevant for each tag - you can simply read them from the example file (inside the for loop), and adapt them, or you can copy and paste these ones, changing the number and internalname.:

    System Message: WARNING/2 (data/howto-write-an-awesome-3-configuration-file.txt, line 125)

    Literal block expected; none found.

    keybinding({ modkey }, "number", function () awful.tag.viewonly(internalname) end):add() keybinding({ modkey, "Control" }, "number", function () internalname.selected = not internalname.selected end):add() keybinding({ modkey, "Shift" }, "number", function () awful.client.movetotag(internalname) end):add() keybinding({ modkey, "Control", "Shift" }, "number", function () awful.client.toggletag(internalname) end):add()

The other useful command is the spawn one, which launches programs. This is in the Standard program section, and is simply:

keybinding({ modkey }, "yourkey", function () awful.spawn(terminal) end):add()

This is why we specified a terminal and browser variable, mostly for neatness. If you don't use a variable, you must put the program name in quotes, otherwise it won't work. You also need to check for conflicts in the shortcuts - the default ones seem to override any user-set ones. You can use this command in a terminal to scan through for the key you wish to check:

cat .config/awesome/rc.lua | grep \"key\"

where key is just the lower-case keyname, ie "o", "t", "p", etc.

  1. Lastly, getting clients to open on tags. This is done right at the end of the file, in the Hooks section. Under function hook_manage(c), which is executed everytime a new client is spawned, just above -- Honor size hints, add this:

    System Message: WARNING/2 (data/howto-write-an-awesome-3-configuration-file.txt, line 143)

    Literal block expected; none found.

    function program(p)

    return c.class:lower():find(p)

    System Message: WARNING/2 (data/howto-write-an-awesome-3-configuration-file.txt, line 145)

    Definition list ends without a blank line; unexpected unindent.

    end if program("firefox") then

    System Message: ERROR/3 (data/howto-write-an-awesome-3-configuration-file.txt, line 147)

    Unexpected indentation.

    awful.client.movetotag(internalname)

    System Message: WARNING/2 (data/howto-write-an-awesome-3-configuration-file.txt, line 148)

    Block quote ends without a blank line; unexpected unindent.

    end

This gets the class name in lower case, and if its a match, moves it to the tag. The class name can be found with xprop | grep WM_CLASS and a click on the relevant window. I simply have one if statement for each program I wish to tag, however I'm sure there's a neater way of doing it with lists or whatever. At the mo, this works for me, so until I learn some more lua, I'll stick with this.

12. Well, thats about it. If you get stuck, post here and i'll try and help out, but let me also point you towards some resources that I found very very helpful: The awesome wiki The awesome wiki article on writing an rc.lua file The awesome wiki Wicked page Some example rc.lua files

Basically, use the wiki! Attached is my rc file for your viewing pleasure - everything works fine, including all my widgets, so if you get stuck it may well help.

Good Luck!