Wibar
The wibar is the status bar at the top (or bottom) of your screen. In this tutorial, you'll build a custom wibar from scratch.
How Wibars Work
A wibar is created with awful.wibar and attached to a screen. The default setup creates one wibar per screen inside the request::desktop_decoration signal:
screen.connect_signal("request::desktop_decoration", function(s)
s.mywibox = awful.wibar {
position = "top",
screen = s,
widget = { ... },
}
end)
The widget property contains your entire bar layout - typically organized into left, center, and right sections.
The Three-Section Pattern
Most wibars use wibox.layout.align.horizontal to create three sections:
widget = {
{ -- Left section
layout = wibox.layout.fixed.horizontal,
-- widgets go here
},
{ -- Center section
layout = wibox.layout.flex.horizontal,
-- widgets go here
},
{ -- Right section
layout = wibox.layout.fixed.horizontal,
-- widgets go here
},
layout = wibox.layout.align.horizontal,
}
- Left - Fixed width, grows from left edge
- Center - Takes remaining space, centers content
- Right - Fixed width, grows from right edge
Creating a Wibar Factory
For cleaner code, create a factory function that builds your wibar:
Create ~/.config/somewm/wibar.lua:
-- wibar.lua
local awful = require("awful")
local wibox = require("wibox")
local beautiful = require("beautiful")
-- Factory function that creates a wibar for each screen
return function(s)
local wibar = awful.wibar {
position = "top",
screen = s,
height = beautiful.wibar_height or 24,
widget = {
{ -- Left section
layout = wibox.layout.fixed.horizontal,
-- We'll add widgets here
},
{ -- Center section
layout = wibox.layout.fixed.horizontal,
},
{ -- Right section
layout = wibox.layout.fixed.horizontal,
},
layout = wibox.layout.align.horizontal,
},
}
return wibar
end
Use it in your rc.lua:
local wibar = require("wibar")
screen.connect_signal("request::desktop_decoration", function(s)
-- Create tags for this screen
awful.tag({ "1", "2", "3", "4", "5" }, s, awful.layout.layouts[1])
-- Create wibar for this screen
s.mywibox = wibar(s)
end)
Adding Standard Widgets
Let's populate the wibar with useful widgets:
-- wibar.lua
local awful = require("awful")
local wibox = require("wibox")
local beautiful = require("beautiful")
return function(s)
-- Create widgets that need the screen
s.mypromptbox = awful.widget.prompt()
s.mylayoutbox = awful.widget.layoutbox {
screen = s,
buttons = {
awful.button({}, 1, function() awful.layout.inc(1) end),
awful.button({}, 3, function() awful.layout.inc(-1) end),
},
}
s.mytaglist = awful.widget.taglist {
screen = s,
filter = awful.widget.taglist.filter.all,
buttons = {
awful.button({}, 1, function(t) t:view_only() end),
awful.button({}, 3, awful.tag.viewtoggle),
awful.button({}, 4, function(t) awful.tag.viewprev(t.screen) end),
awful.button({}, 5, function(t) awful.tag.viewnext(t.screen) end),
},
}
s.mytasklist = awful.widget.tasklist {
screen = s,
filter = awful.widget.tasklist.filter.currenttags,
buttons = {
awful.button({}, 1, function(c)
c:activate { context = "tasklist", action = "toggle_minimization" }
end),
awful.button({}, 3, function()
awful.menu.client_list { theme = { width = 250 } }
end),
},
}
local wibar = awful.wibar {
position = "top",
screen = s,
widget = {
{ -- Left section
layout = wibox.layout.fixed.horizontal,
s.mytaglist,
s.mypromptbox,
},
s.mytasklist, -- Center section
{ -- Right section
layout = wibox.layout.fixed.horizontal,
wibox.widget.systray(),
wibox.widget.textclock(),
s.mylayoutbox,
},
layout = wibox.layout.align.horizontal,
},
}
return wibar
end
Adding Custom Widgets
Add your own widgets from modules:
-- At the top of wibar.lua
local my_clock = require("widgets.clock")
local my_battery = require("widgets.battery")
-- In the right section:
{ -- Right section
layout = wibox.layout.fixed.horizontal,
wibox.widget.systray(),
my_battery,
my_clock,
s.mylayoutbox,
},
Adding Separators
Create visual separation between widget groups:
local function separator()
return wibox.widget {
{
widget = wibox.widget.separator,
orientation = "vertical",
forced_width = 1,
color = beautiful.fg_normal .. "40", -- 25% opacity
},
margins = { left = 8, right = 8 },
widget = wibox.container.margin,
}
end
-- Use in your layout:
{ -- Right section
layout = wibox.layout.fixed.horizontal,
wibox.widget.systray(),
separator(),
my_battery,
separator(),
my_clock,
separator(),
s.mylayoutbox,
},
Wibar Properties
For a complete reference of all wibar properties, see the Wibar Properties Reference.
Key properties include:
position-"top","bottom","left","right"height/width- Size in pixelsmargins- Create floating effect with gapsshape- Custom shape function (e.g., rounded corners)bg/fg- Colors (can include alpha for transparency)
Styling the Wibar
Through Theme Variables
In your theme.lua:
theme.wibar_bg = "#282828"
theme.wibar_fg = "#ebdbb2"
theme.wibar_height = 28
theme.wibar_border_color = "#3c3836"
theme.wibar_border_width = 1
Inline Styling
awful.wibar {
position = "top",
screen = s,
bg = beautiful.wibar_bg .. "e0", -- Slightly transparent
fg = beautiful.wibar_fg,
border_width = 1,
border_color = beautiful.wibar_border_color,
}
Complete Example
Here's a complete wibar module with all features:
-- wibar.lua
local awful = require("awful")
local wibox = require("wibox")
local gears = require("gears")
local beautiful = require("beautiful")
-- Optional: import custom widgets
-- local widgets = require("widgets")
-- Separator widget
local function separator()
return wibox.widget {
{
orientation = "vertical",
forced_width = 1,
color = beautiful.fg_normal .. "30",
widget = wibox.widget.separator,
},
top = 6,
bottom = 6,
left = 8,
right = 8,
widget = wibox.container.margin,
}
end
-- Wibar factory function
return function(s)
-- Per-screen widgets
s.mypromptbox = awful.widget.prompt()
s.mylayoutbox = awful.widget.layoutbox {
screen = s,
buttons = {
awful.button({}, 1, function() awful.layout.inc(1) end),
awful.button({}, 3, function() awful.layout.inc(-1) end),
awful.button({}, 4, function() awful.layout.inc(-1) end),
awful.button({}, 5, function() awful.layout.inc(1) end),
},
}
s.mytaglist = awful.widget.taglist {
screen = s,
filter = awful.widget.taglist.filter.all,
buttons = {
awful.button({}, 1, function(t) t:view_only() end),
awful.button({ modkey }, 1, function(t)
if client.focus then
client.focus:move_to_tag(t)
end
end),
awful.button({}, 3, awful.tag.viewtoggle),
awful.button({}, 4, function(t) awful.tag.viewprev(t.screen) end),
awful.button({}, 5, function(t) awful.tag.viewnext(t.screen) end),
},
}
s.mytasklist = awful.widget.tasklist {
screen = s,
filter = awful.widget.tasklist.filter.currenttags,
buttons = {
awful.button({}, 1, function(c)
c:activate { context = "tasklist", action = "toggle_minimization" }
end),
awful.button({}, 3, function()
awful.menu.client_list { theme = { width = 250 } }
end),
awful.button({}, 4, function() awful.client.focus.byidx(-1) end),
awful.button({}, 5, function() awful.client.focus.byidx(1) end),
},
}
-- Create the wibar
local wibar = awful.wibar {
position = "top",
screen = s,
height = beautiful.wibar_height or 28,
bg = beautiful.wibar_bg,
fg = beautiful.wibar_fg,
widget = {
{ -- Left section
layout = wibox.layout.fixed.horizontal,
s.mytaglist,
separator(),
s.mypromptbox,
},
{ -- Center section
s.mytasklist,
layout = wibox.layout.flex.horizontal,
},
{ -- Right section
layout = wibox.layout.fixed.horizontal,
wibox.widget.systray(),
separator(),
awful.widget.keyboardlayout(),
separator(),
wibox.widget.textclock(" %a %b %d, %H:%M "),
separator(),
s.mylayoutbox,
},
layout = wibox.layout.align.horizontal,
},
}
return wibar
end
Multiple Wibars
You can have multiple wibars on a screen:
screen.connect_signal("request::desktop_decoration", function(s)
-- Top bar with tags and systray
s.top_wibar = awful.wibar {
position = "top",
screen = s,
widget = { ... },
}
-- Bottom bar with tasklist only
s.bottom_wibar = awful.wibar {
position = "bottom",
screen = s,
widget = s.mytasklist,
}
end)
Toggling Visibility
Hide/show the wibar with a keybinding:
awful.key({ modkey }, "b", function()
local s = awful.screen.focused()
s.mywibox.visible = not s.mywibox.visible
end, { description = "toggle wibar", group = "awesome" }),
Troubleshooting
Wibar not showing
- Check that you're returning the wibar from your factory function
- Verify it's being called in
request::desktop_decoration - Try adding explicit
heightto ensure it has size
Widgets cut off
The wibar may be too short. Increase the height:
awful.wibar {
height = 32, -- Increase from default
...
}
Systray icons not showing
The systray can only be on one screen. Make sure it's only added once:
-- Only add systray to primary screen
if s == screen.primary then
-- add wibox.widget.systray()
end
Next Steps
- Wibar Properties Reference - Complete wibar configuration reference
- Widgets - Create custom widgets for your wibar
- Theme - Style your wibar
- awful.wibar (AwesomeWM docs) - Upstream API reference