ZNHOO Whatever you are, be a good one!


  1. X terminal emulator
  2. Autostart
  3. Menu
  4. reboot/shutdown
  5. Theme
  6. wallpaper
  7. Transparency
  8. Screenshot
  9. slock
    1. xautolock
  10. st terminal emulator

Awesome is a lightweight window manager and yet can be highly cusotmized to your own needs. This post mainly focuses on awesome configuration at ~/.config/awesome/rc.lua.

  1. Before everything else, please read awesome autostart.
  2. Also read hotkeys from default lefttop menu or by Super-s.

X terminal emulator

st and lilyterm are recommended in that they are lightweight and supports UTF8 and CJK by nature.

-- rc.lua

terminal = "st"


Desktop (XFCE, KDE etc.) has many autostart .desktop files in /etc/xdg/autostart/ or ~/.config/autostart/ to launch default applications on startup (i.e. input method, power manager etc.). Awesome requires manual settings:

Here is an example of VBoxClient-all autostart with awesome. Create ~/.config/awesome/autostart.sh:

#!/usr/bin/env bash

function run {
  if ! pgrep $1 ;

run VBoxClient-all
run fcitx-autostart

Make it executable:

[user@host ~]$ chmod +x ~/.config/awesome/autostart.sh

Check autostart.sh:

[user@host ~]$ ~/.config/awesome/autostart.sh

You can add any other programs to autostart by appending run executable [--arguments] to the end of autostart.sh.

Finally, add to the end of ~/.config/awesome/rc.lua:

-- awful.spawn.with_shell("~/.config/awesome/autostart.sh")
awful.spawn.with_shell(awful.util.getdir("config") .. "/autostart.sh")

To make sure modification syntax is correct:

user@tux ~ # awesome -k

Please be noted that, awesome restart does not restart scripts in autostart.sh.


-- rc.lua

myawesomemenu = {
   { "hotkeys", function() return false, hotkeys_popup.show_help end},
   { "manual", terminal .. " -e man awesome" },
   { "edit config", editor_cmd .. " " .. awesome.conffile },
   { "restart", awesome.restart },
   { "quit", function() awesome.quit() end},
   { "reboot", "dbus-send --system --print-reply --dest='org.freedesktop.ConsoleKit' /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Restart" },
   { "shutdown", "dbus-send --system --print-reply --dest='org.freedesktop.ConsoleKit' /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop" },
   { "hibernate", "dbus-send --system --print-reply --dest='org.freedesktop.DeviceKit.Power' /org/freedesktop/DeviceKit/Power org.freedesktop.DeviceKit.Power.Hibernate" },
   { "suspend", "dbus-send --system --print-reply --dest='org.freedesktop.DeviceKit.Power' /org/freedesktop/DeviceKit/Power org.freedesktop.DeviceKit.Power.Suspend" },

appsmenu = {
   { "emc", "emc" },
   { "sound", "st -e alsamixer" },
   { "thunar" , "thunar" },
   { "firefox", "firefox" },
   { "telegram", "telegram-desktop" }

mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
                                    { "apps", appsmenu },
                                    { "sound", "st -e alsamixer" },
                                    { "editor", "emc" },
                                    { "thunar" , "thunar" },
                                    { "browser", "firefox" },
                                    { "terminal", terminal }

mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
                                     menu = mymainmenu })

-- Menubar configuration
menubar.utils.terminal = terminal -- Set the terminal for applications that require it

-- tell awesome to search per-user .desktop files
app_folders = { "/usr/share/applications/", "~/.local/share/applications/" }
-- }}}

Trigger menu bar by Mod-p binding and then type the application keywords.


Set the relevant menu entries. Make sure consolekit service is launched!

-- rc.lua

{ "reboot", "dbus-send --system --print-reply --dest='org.freedesktop.ConsoleKit' /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Restart" },
{ "shutdown", "dbus-send --system --print-reply --dest='org.freedesktop.ConsoleKit' /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop" },
{ "hibernate", "dbus-send --system --print-reply --dest='org.freedesktop.DeviceKit.Power' /org/freedesktop/DeviceKit/Power org.freedesktop.DeviceKit.Power.Hibernate" },
{ "suspend", "dbus-send --system --print-reply --dest='org.freedesktop.DeviceKit.Power' /org/freedesktop/DeviceKit/Power org.freedesktop.DeviceKit.Power.Suspend" },


First, we create per-user theme directory and copy default theme there where we will do customization.

user@tux ~ $ mkdir -p ~/.config/awesome/themes/
user@tux ~ $ cp -a /usr/share/awesome/themes/default/ ~/.config/awesome/themes/

Afterwards, change beautiful.wallpaper value to the new directory in rc.lua:

-- rc.lua

-- beautiful.init(gears.filesystem.get_themes_dir() .. "default/theme.lua")
beautiful.init(awful.util.getdir("config") .. "/themes/default/theme.lua")
-- or
beautiful.init(awful.util.get_configuration_dir() .. "/themes/default/theme.lua")

For example, we can set useless gap to 5:

-- rc.lau

beautiful.useless_gap = 5


To set a wallpaper, change theme.wallpaper value in theme.lua:

-- theme.lua
theme.wallpaper = "~/.config/awesome/themes/default/wallpaper.png"

Alternatively, we can set wallpaper in rc.lua before function set_wallpaper(s):

-- rc.lua

beautiful.wallpaper = awful.util.get_configuration_dir() .. "sub-path/to/wallpaper.png"


For wibox transparency, append transparency value (00 - FF) to bg_normal in theme.lua. 00 means totally transparent while FF is not transparent.

-- theme.lua

--theme.bg_normal     = "#222222"
theme.bg_normal     = "#22222200"

Alternatively, append bg = beautiful.bg_normal .. "0" to s.mywibox.

-- rc.lua

s.mywibox = awful.wibar({ position = "top", screen = s, bg = beautiful.bg_normal .. "00" })


root@tux / # emerge -avt scrot
user@tux ~ $ scrot -s -q1 -cd3 -t20

Add to the globalkeys array:

-- rc.lua
awful.key({ }, "Print", function () awful.util.spawn_with_shell("sleep 0.5 && scrot -s -q1 -e 'mv $f ~/Pictures/scrot/ 2>/dev/null'", false) end, {description = "take screenshot", group = "launcher"}),

Press Prtsc key to take screenshot. We use awful.util.spawn_with_shell instead of awful.util.spawn and also append sleep 0.5 before scrot, otherwise we cannot use -s to take selected region.


root@tux / # echo 'x11-misc/slock savedconfig' >> /etc/portage/package.use/slock
root@tux / # emerge -avt slock (Additionally, I have add in the *dpms* patch.)

Set key binding:

-- rc.lua

awful.key({ modkey, "Control" }, "l", function () awful.util.spawn("slock", false) end, {description = "lock screen"})
awful.key({ }, "XF86ScreenSaver", function () awful.util.spawn("slock", false) end, {description = "lock screen"})

XF86ScreenSaver means Fn + F2 key combination. To determine the key name, just press relevant key or binding in Emacs GUI or resort to sev, showkey xmodkey etc.


To automatically lock screen after a period of inactivity, we use xautolock:

root@tux / # emerge -avt xautolock

We create a script autostart script ~/opt/bin/xautoslock.sh:


exec xautolock -detectsleep \
  -time 3 -locker "slock" \
  -notify 30 \
  -notifier "notify-send -u critical -t 10000 -- 'LOCKING screen in 30 seconds'"

Then, assign executable permission (chmod +x xautoslock.sh) before appending it to autostart.sh:

run ~/opt/bin/xautoslock.sh

st terminal emulator

Firstly, we enable savedconfig:

root@tux / # echo 'x11-terms/st savedconfig' >> /etc/portage/package.use/st

st is quite basic and lack features like copy/paste, scrollback etc. We should apply a few local patches by /etc/portage/patches before they are merged into portage:

# make sure the slot number is correct
root@tux / # mkdir -p /etc/portage/patches/x11-terms/st-0.7

If the directory made does not contain version and/or slot specifier (/etc/portage/patches/x11-terms/st/), then everytime you emerge (i.e. update) the package, patches are definitely applied, which would fail if new versions in portage already apply the patches, causing patches to be applied twice.

Grab patch files from st official page and put them into directory just created. clipboard, scrollback, spoiler, visualbell, xresources and solarized are recommended. solarized-both-0.8.1 has bug and please use solarized-dark-0.8.1 instead.

Sometimes, a patch must be applied before another, we can rename the patch files with number prefix as patches are apllied in lexicographical order.

Then step into the package's ebuild directory and check patches:

root@tux / # cd /us/portage/x11-terms/st
root@tux / # ebuild st-0.7.ebuild clean prepare

We get the following log:

* st-0.7.tar.gz BLAKE2B SHA512 size ;-) ...
>>> Unpacking source...
>>> Unpacking st-0.7.tar.gz to /var/tmp/portage/x11-terms/st-0.7/work
>>> Source unpacked in /var/tmp/portage/x11-terms/st-0.7/work
>>> Preparing source in /var/tmp/portage/x11-terms/st-0.7/work/st-0.7 ...
* Applying st-clipboard-0.7.diff ...
* Applying st-scrollback-0.7.diff ...
* User patches applied.
* Checking existence of //etc/portage/savedconfig//x11-terms/st-0.7 ...
* found //etc/portage/savedconfig//x11-terms/st-0.7
* Building using saved configfile //etc/portage/savedconfig//x11-terms/st-0.7
>>> Source prepared.

We find a line User patches applied. Bt this patching method, there is no need to update ebuild as long as it is EAPI6 and/or include eapply_user instruction.

st behaviour could be further adjusted from savedconfig. By default, a copy will be saved as /etc/portage/savedconfig/x11-terms/st-0.7. For example, we can change default shell, termname, font, etc. To avoid re-compiling upon configuration update, we apply xresources patch that supports Xresources.

If a patch happended to update saveconfig USE, and later on you removed the patch. The compiling would be probably fail! Either remove saved config or take back the patch.

Finally, just emerge!

As of 0.7, the scrollback patch ignores saved config and report histsize undeclared. Either bump to new slot or remove saved config file.

To change termname to xterm-256color:

# ~/.Xresources

st.termname: xterm-256color