Uh, so this is maybe a weird post to put up after not writing anything for a while, but here I am.

I’m a big fan of the Awesome window manager. It’s definitely not for everyone, but I switched to it a while ago and have really become a fan of how it works. I don’t even use most of its features, honestly, but I like that they’re there. And I really appreciate that you can change almost any aspect of how it works. One weakness of it, though, is that it isn’t very well-documented. You kind of have to dig into the internals to figure out how things work, or get lucky and find some internet rando’s blog post telling you how to do the thing you want to do.

In this blog post, I, internet rando, will tell you about one Awesome customization I’ve done, to give each tag (workspace) button a different color.

A picture of a cool bar!

(By the way, these instructions are written for Awesome 4.2. You might be able to follow along for other versions, though.)

Why would you even do this

Okay, you might think it looks kind of silly to have them all different colors like that. Well, you’ve kind of got a point there. I have synesthesia, so I think this helps me organize the workspaces in my head.

But as a normal person, you could use this technique to, for example, make your “work” workspaces blue and your “play” workspaces orange, or something. Set up a fun little color-coding scheme. I’m assuming that if you’re still reading this page, you have some reason to want to do this.

Also, this might not be the best way to go about doing this. I basically figured this out by trial and error, so your mileage may vary. ¯\_(ツ)_/¯

Okay, how do I do this

Obviously, the first thing you need to do is come up with your color scheme.

Locate your theme file by finding the line beautiful.init('/path/to/theme.lua'). Open path/to/theme.lua and add a new item which is just a list of all the colors, in the order that you want them to appear. (You can write some helpful comments about which workspace they match up with.)

theme.workspace_colors = {
    "#FFEE2A", -- Star
    "#AD4CD3", -- Flower
    "#AE3600", -- Coffee
    "#61D82B", -- Atom
    "#007FFF", -- Moon
    "#E11111", -- Communism
    "#FFFD00", -- Pencil
    "#000BFF", -- Music
    "#26BCFF", -- Snowman
} 

Now we can access this data from our rc.lua file by referring to beautiful.workspace_colors. When we construct our taglist widget, we’ll have to pass it this list of colors as an additional parameter. We’ll then modify the widget code to accept this new parameter and do something useful with it.

Our first order of business is to pass these colors to the taglist as we construct it. Open up your rc.lua file. The actual widget is constructed on the line which calls the awful.tag function. For me, it looks like this, but for you it obviously will have your workspace names and layouts instead.

-- Each screen has its own tag table.
awful.tag({ " ★ ", " ⚘ ", " ☕ ", " ⚛ ", " 🌙 ", " ☭ ", " ✎ ", " ♫ "," ⛄ "}, s,
        awful.layout.layouts[2])

We’ll just stick our new workspace_colors array on the end as another argument to this function:

-- Each screen has its own tag table.
awful.tag({ " ★ ", " ⚘ ", " ☕ ", " ⚛ ", " 🌙 ", " ☭ ", " ✎ ", " ♫ "," ⛄ "}, s,
        awful.layout.layouts[2], beautiful.workspace_colors)

Great! Now comes the tricky part: we’ve got to go edit the taglist widget code to actually use this data. Don’t worry, it’s not that difficult.

First, you’ll have to figure out where Awesome is keeping its configuration files for the awful library (which is what’s in charge of the top bar, I think?) For me, they were located at /usr/local/share/awesome/lib/awful (what a mouthful!), but yours might be in a slightly different location. (They might be in /usr/share/awesome/lib/awful instead?)

First, we need to edit tag.lua, which controls the behavior of individual tags and also constructs the initial list of tags. Open it up in your favorite text editor as root.

Find the function tag.new. It should look something like this:

function tag.new(names, screen, layout)
    screen = get_screen(screen or 1)
    -- True if `layout` should be used as the layout of each created tag
    local have_single_layout = (not layout) or (layout.arrange and layout.name)
    local tags = {} 
    for id, name in ipairs(names) do
        local l = layout
        if not have_single_layout then
            l = layout[id] or layout[1]
        end
        table.insert(tags, id, tag.add(name, {screen = screen, layout = l})) -- <== LOOK
        -- Select the first tag.
        if id == 1 then
            tags[id].selected = true
        end
    end
    
    return tags
end

The line I’ve marked with <== LOOK is the line where each tag variable is created individually. The ID number of the tag is in the variable id.

And conveniently, this function just takes the parameters that we passed into awful.tag in rc.lua. Since we added the color array as the last argument, let’s just add that at the end, and give each tag a color attribute that is the id‘th color in the array:

function tag.new(names, screen, layout, colors) -- <== NEW
    screen = get_screen(screen or 1)
    -- True if `layout` should be used as the layout of each created tag
    local have_single_layout = (not layout) or (layout.arrange and layout.name)
    local tags = {} 
    for id, name in ipairs(names) do
        local l = layout
        if not have_single_layout then
            l = layout[id] or layout[1]
        end
        table.insert(tags, id, tag.add(name, {screen = screen, layout = l,
                         color = colors[id]})) -- <== NEW
        -- Select the first tag.
        if id == 1 then
            tags[id].selected = true
        end
    end
    
    return tags
end

(If you want to, you can add to the comment above the function, explaining what the new parameter is for.)

So now each tag has a color attribute associated with it which is taken from our theme file. Now all that’s left is to rig up the taglist widget to actually display the tags in these colors.

The file that we need is under the awful directory as well, at widgets/taglist.lua. Edit this one as root, too.

Find this line:

if t.selected then
    bg_color = bg_focus
    fg_color = fg_focus

    if args.shape_focus or theme.taglist_shape_focus then
        theme.taglist_shape_focus
    end
    -- ...... more stuff down here

Changing the color of these tags is accomplished by setting the bg_color and fg_color variables. We want the default foreground (i.e. text) color to just be the tag’s color. If a tag has a special state, it’ll get overwritten in this if statement, so we can set the default color by setting it before anything else:

fg_color = t.color
if t.selected then
    -- etc

(Here, t is one of the tag objects that we created back in tag.lua.)

Finally, we want selected tags to have the tag color as background. It’s pretty obvious how we can accomplish this:

fg_color = t.color
if t.selected then
    bg_color = t.color -- <== NEW
    fg_color = fg_focus

    if args.shape_focus or theme.taglist_shape_focus then
        theme.taglist_shape_focus
    end
    -- ...... more stuff down here

And voila! Save your files, restart awesome and it should work. Enjoy!


Side note: I really wish more desktop environments supported giving workspaces individual colors. Maybe I’d be the only one who’d appreciate that feature, though…