Preface
Goal: Main modules in modularized configuration.
Table of Content
Artefacts
Now consider have a walk, moving some codes to files in main directory.
$ tree main
main
├── error-handling.lua
├── layouts.lua
├── menu.lua
├── rules.lua
├── signals.lua
├── tags.lua
└── user-variables.lua
0 directories, 7 files
We have already moved error-handling.lua
and user-variables.lua
in previous article.
We will discuss here about the rest five: layouts
,
tags
, menu
, rules
, and signal
.
Calling Script
We are going to call these scripts in rc.lua
.
-- Custom Local Library
local main = {
layouts = require ( "main.layouts" ),
tags = require ( "main.tags" ),
menu = require ( "main.menu" ),
rules = require ( "main.rules" ),
}
Do not get intimidated with codes above.
These can be explained step by step.
1: Layouts
The layout icon can be seen in top-right statusbar.
Module Script
You can add or remove, layout using this script below:
-- Standard awesome library
local awful = require ( "awful" )
local _M = {}
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function _M . get ()
-- Table of layouts to cover with awful.layout.inc, order matters.
local layouts = {
awful . layout . suit . floating , -- 1:
awful . layout . suit . tile , -- 2:
awful . layout . suit . tile . left , -- 3:
awful . layout . suit . tile . bottom , -- 4:
awful . layout . suit . tile . top , -- 5:
awful . layout . suit . fair , -- 6:
awful . layout . suit . fair . horizontal , -- 7:
awful . layout . suit . spiral , -- 8:
awful . layout . suit . spiral . dwindle , -- 9:
awful . layout . suit . max , -- 10:
awful . layout . suit . max . fullscreen , -- 11:
awful . layout . suit . magnifier , -- 12:
awful . layout . suit . corner . nw -- 13:
-- awful.layout.suit.corner.ne,
-- awful.layout.suit.corner.sw,
-- awful.layout.suit.corner.se,
}
return layouts
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
return setmetatable (
{},
{ __call = function ( _ , ... ) return _M . get ( ... ) end }
)
Now we have these available: floating
, tile
, tile,left
,
tile.bottom
, tile.top
, fair
, fair.horizontal
,
spiral
, spiral.dwindle
, max
, max.fullscreen
, magnifier
,
corner.nw
. You can also add layout using other third party library.
.
I put number a comment,
because I want to give different layout for different tag.
what I mean is, this comment is required.
Layout Preview
It is easier to understand the layout using image.
Calling Script
In main configuration:
-- Custom Local Library
local main = {
layouts = require ( "main.layouts" )
}
-- Layouts
RC . layouts = main . layouts ()
Standar Tag
Standard tags are using number.
-- Standard awesome library
local awful = require ( "awful" )
local _M = {}
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function _M . get ()
tags = {}
awful . screen . connect_for_each_screen ( function ( s )
-- Each screen has its own tag table.
tags [ s ] = awful . tag (
{ "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" }, s , RC . layouts [ 1 ]
)
end )
return tags
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
return setmetatable (
{},
{ __call = function ( _ , ... ) return _M . get ( ... ) end }
)
.
Remember that RC.layouts[1]
is,
awful.layout.suit.floating
.
Calling Script
In main configuration:
-- Custom Local Library
local main = {
layouts = require( "main.layouts" ) ,
tags = require( "main.tags" )
}
-- Tags
RC.tags = main.tags()
Custom Tag
What about different tag names?
Well, you can rewrite the script as below:
function _M . get ()
local tags = {}
local tagpairs = {
-- names = { "term", "net", "edit", "place", 5, 6, 7, 8, 9 },
names = {
"❶ 一 term" , "❷ 二 net" , "❸ 三 edit" ,
"❹ 四 place" , "❺ 五 mail" ,
" ❻ 六" , "❼ 七" , " ❽ 八" , "❾ 九" },
layout = {
RC . layouts [ 1 ], RC . layouts [ 2 ], RC . layouts [ 4 ],
RC . layouts [ 5 ], RC . layouts [ 6 ], RC . layouts [ 12 ],
RC . layouts [ 9 ], RC . layouts [ 3 ], RC . layouts [ 7 ]
}
}
awful . screen . connect_for_each_screen ( function ( s )
-- Each screen has its own tag table.
tags [ s ] = awful . tag ( tagpairs . names , s , tagpairs . layout )
end )
return tags
end
This menu is very helpful for beginner.
You can setup manually like what this article explain,
or you can use third party to build XDG menu,
for works with Awesome WM.
Module Script: Initialization.
This script is a little bit long.
It takes some libraries to be loaded,
and predefined variables to be set.
-- Standard awesome library
local awful = require ( "awful" )
local hotkeys_popup = require ( "awful.hotkeys_popup" ). widget
-- Theme handling library
local beautiful = require ( "beautiful" ) -- for awesome.icon
local M = {} -- menu
local _M = {} -- module
-- reading
-- https://awesomewm.org/apidoc/popups%20and%20bars/awful.menu.html
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- This is used later as the default terminal and editor to run.
-- local terminal = "xfce4-terminal"
local terminal = RC . vars . terminal
-- Variable definitions
-- This is used later as the default terminal and editor to run.
local editor = os.getenv ( "EDITOR" ) or "nano"
local editor_cmd = terminal .. " -e " .. editor
Module Script: Configuration Values
Right below the initialization,
lays code that set configuration values.
M . awesome = {
{ "hotkeys" , function ()
hotkeys_popup . show_help ( nil , awful . screen . focused ())
end },
{ "manual" , terminal .. " -e man awesome" },
{ "edit config" , editor_cmd .. " " .. awesome . conffile },
{ "Terminal" , terminal },
{ "Shutdown/Logout" , "oblogout" },
{ "restart" , awesome . restart },
{ "quit" , function () awesome . quit () end }
}
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function _M . get ()
-- Main Menu
local menu_items = {
{ "awesome" , M . awesome , beautiful . awesome_subicon },
{ "open terminal" , terminal }
}
return menu_items
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
return setmetatable (
{},
{ __call = function ( _ , ... ) return _M . get ( ... ) end }
)
.
And the result is:
Calling Script
In main configuration:
-- Custom Local Library
local main = {
layouts = require( "main.layouts" ) ,
tags = require( "main.tags" ) ,
menu = require( "main.menu" )
}
-- Menu
RC.mainmenu = awful.menu({ items = main.menu() })
RC.launcher = awful.widget.launcher(
{ image = beautiful.awesome_icon, menu = RC.mainmenu }
)
menubar.utils.terminal = RC.vars.terminal
Of course we can append menu items.
It is easy actually, by adding these setting.
M . favorite = {
{ "caja" , "caja" },
{ "thunar" , "thunar" },
{ "geany" , "geany" },
{ "clementine" , "clementine" },
{ "firefox" , "firefox" , awful . util . getdir ( "config" ) .. "/firefox.png" },
{ "chromium" , "chromium" },
{ "&firefox" , "firefox" },
{ "&thunderbird" , "thunderbird" },
{ "libreoffice" , "libreoffice" },
{ "transmission" , "transmission-gtk" },
{ "gimp" , "gimp" },
{ "inkscape" , "inkscape" },
{ "screenshooter" , "xfce4-screenshooter" }
}
M . network_main = {
{ "wicd-curses" , "wicd-curses" },
{ "wicd-gtk" , "wicd-gtk" }
}
And add those variables above in main menu.
function _M . get ()
-- Main Menu
local menu_items = {
{ "awesome" , M . awesome , beautiful . awesome_subicon },
{ "open terminal" , terminal },
{ "network" , M . network_main },
{ "favorite" , M . favorite }
}
return menu_items
end
And the result is:
4: Rules
I mostly just cut and paste the rule.
This is long, it has long documentation,
and maybe deserve its own article.
-- Standard awesome library
local awful = require ( "awful" )
-- Theme handling library
local beautiful = require ( "beautiful" )
local _M = {}
-- reading
-- https://awesomewm.org/apidoc/libraries/awful.rules.html
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function _M . get ( clientkeys , clientbuttons )
local rules = {
-- All clients will match this rule.
{ rule = { },
properties = {
border_width = beautiful . border_width ,
border_color = beautiful . border_normal ,
focus = awful . client . focus . filter ,
raise = true ,
keys = clientkeys ,
buttons = clientbuttons ,
screen = awful . screen . preferred ,
placement = awful . placement . no_overlap + awful . placement . no_offscreen
}
},
-- Floating clients.
{ rule_any = {
instance = {
"DTA" , -- Firefox addon DownThemAll.
"copyq" , -- Includes session name in class.
"pinentry" ,
},
class = {
"Arandr" ,
"Blueman-manager" ,
"Gpick" ,
"Kruler" ,
"MessageWin" , -- kalarm.
"Sxiv" ,
"Tor Browser" , -- Needs a fixed window size to avoid fingerprinting by screen size.
"Wpa_gui" ,
"veromix" ,
"xtightvncviewer" },
-- Note that the name property shown in xprop might be set slightly after creation of the client
-- and the name shown there might not match defined rules here.
name = {
"Event Tester" , -- xev.
},
role = {
"AlarmWindow" , -- Thunderbird's calendar.
"ConfigManager" , -- Thunderbird's about:config.
"pop-up" , -- e.g. Google Chrome's (detached) Developer Tools.
}
},
properties = {
floating = true
}
},
-- Add titlebars to normal clients and dialogs
{ rule_any = {
type = { "normal" , "dialog" }
},
properties = {
titlebars_enabled = true
}
},
-- Set Firefox to always map on the tag named "2" on screen 1.
-- { rule = { class = "Firefox" },
-- properties = { screen = 1, tag = "2" } },
}
return rules
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
return setmetatable (
{},
{ __call = function ( _ , ... ) return _M . get ( ... ) end }
)
.
Calling Script
In main configuration:
-- Custom Local Library
local main = {
layouts = require( "main.layouts" ) ,
tags = require( "main.tags" ) ,
menu = require( "main.menu" ) ,
rules = require( "main.rules" ) ,
}
-- Rules
awful.rules.rules = main.rules( clientkeys, clientbuttons)
You can later change the code to
-- Rules
awful.rules.rules = main.rules(
binding.clientkeys() ,
binding.clientbuttons()
)
But now, leave it that way.
Since we haven’t touch the binding
section.
5: Signals
On most my Awesome WM time,
I rarely make any customization in this signal section.
-- Standard awesome library
local gears = require ( "gears" )
local awful = require ( "awful" )
-- Widget and layout library
local wibox = require ( "wibox" )
-- Theme handling library
local beautiful = require ( "beautiful" )
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Signal function to execute when a new client appears.
client . connect_signal ( "manage" , function ( c )
-- Set the windows at the slave,
-- i.e. put it at the end of others instead of setting it master.
-- if not awesome.startup then awful.client.setslave(c) end
if awesome . startup
and not c . size_hints . user_position
and not c . size_hints . program_position then
-- Prevent clients from being unreachable after screen count changes.
awful . placement . no_offscreen ( c )
end
end )
-- Enable sloppy focus, so that focus follows mouse.
client . connect_signal ( "mouse::enter" , function ( c )
c : emit_signal ( "request::activate" , "mouse_enter" , { raise = false })
end )
client . connect_signal ( "focus" , function ( c ) c . border_color = beautiful . border_focus end )
client . connect_signal ( "unfocus" , function ( c ) c . border_color = beautiful . border_normal end )
I put titlebar signal in other files.
-- Custom Local Library: Common Functional Decoration
require ( "deco.titlebar" )
You can choose not to have titlebar.
People doing ricing, love borderless window.
Calling Script
In main configuration:
-- Signals
require ( "main.signals" )
Since it does not return value,
that code above is enough.
What is Next?
Consider continue reading [ Awesome WM - Binding Modules ].
There are, some interesting topic,
about refactoringAwesome WM
using Lua
.
What do you think ?