This has been updated for Awesome 3.5
I have long been interested in tiling window managers, which would seem to offer the flexibility I crave. But switching is painful when you want your machine to be as functional as much as possible. On at least two occasions I have switched … and very quickly switched back when problems were encountered.
So just for the fun of it, I have decided to give it another go … in a way that can be gradually worked into functionality.
But first, what exactly is a tiling window manager? Well a conventional window manager works with overlapping windows where windows can stack on top of each other and overlap. A tiling window manager on the other hand uses tiling to maximise the size of every displayed window.
Or in other words, if you want to make the maximum use of space on your screen, a stacking window manager usually asks you to manually move and resize windows yourself whereas a tiling window manager does it all automatically. Although with a tiling window manager, you will need to rotate amongst different tiling layouts to suit.
Tiling window managers tend to be keyboard driven rather than mouse driven, but this is merely an aspect of their implementation.
A Testing Environment
The key to setting up any window manager gradually over time without losing an existing working environment, is to create a separate display which a new window manager can control. This can be quite easily accomplished with a nesting X server, which is provided by the xserver-xephyr package.
As to the choice of window manager, the title of this post gives away the secret – Awesome. Of course the same method works for other window managers too.
The first step is to install the required packages :-
sudo apt-get install xserver-xephyr awesome awesome-extra
The next step is to create a simple shell script to start the nested X server. This basically starts the nested X server with a sensible screen size, and sets the $DISPLAY environment variable so that any further X programs are directed to communicate with the nested X server. The nested X server simply starts up as a standard window within which Awesome operates. The script looks like :-
#!/bin/sh
Xephyr -ac -reset -screen 1280x1000 :1 &
export DISPLAY=:1.0
sleep 5
awesome --config ~/src/site/etc/awesome/config.lua
The sleep command in there is to wait until X has settled down before trying to manage it … without this, it is possible that awesome will fail to open the display (on a slower laptop it worked without; on a faster desktop it did not). The parameter to awesome is to set the preferred location for the configuration file (which I will describe next), although you can leave it out to use the default.
Don’t start it yet! Before doing that, copy the default configuration file to the specified location so you have something to work with :-
cp /etc/xdg/awesome/rc.lua ~/src/site/etc/awesome/config.lua
It’s All In The Repository
The custom configuration file I specified just happens to point to a directory and file within the working copy of a Subversion repository. Using a repository for configuration files has all sorts of benefits; not least of which is to reverse “poor” choices made along the way. Whilst describing how to get one set up is beyond the purpose of this post, it is well worth doing.
Of course if you are working with a repository, it is important to remember to commit changes at every stage :-
% svn add ~/src/site/etc/awesome
A /home/mike/src/site/etc/awesome
A /home/mike/src/site/etc/awesome/config.lua
% svn commit ~/src/site/etc/awesome -m "Awesome: Initial Configuration from default"
Adding src/site/etc/awesome
Adding src/site/etc/awesome/config.lua
Transmitting file data .
Committed revision 166.
I won’t be documenting every single commit, but they are all in there!
It is also helpful (at this stage) to create a symlink between the default configuration directory (~/.config/awesome) and the working copy of your repository. The configuration directory can probably be changed, but one thing at a time!
Status Bar Size
One of the annoyances I remember from the last time I played with Awesome, was the tiny size of the status bar. It is all very well maximising the size of the main screen area, but some of us have high resolution screens and tired old eyes! Within the config.lua file (or whatever you named your file), look for :-
mywibox[s] = awful.wibox({ position = "top", screen = s})
And change it to add a height parameter :-
mywibox[s] = awful.wibox({ position = "top", screen = s, height=32 })
The exact choice of size is of course down to personal preferences! However changing the size also means changing the font would be wise :-
awesome.font = "LMSans10 10"
Making the font too much larger will result in some display oddities … at least for now.
Adding A Title Bar
In theory, there is no need for a title bar with a tiling window manager, but I guess I am a little too conventional as a window without a title bar still looks a little weird to me. Plus my shell prompts stick useful bits of information into the window title bar and I would really rather hang on to that extra information. Still, drawing title bars on windows turns out to be really simple … just find the existing code to do so and :-
local titlebars_enabled = true
Some appearance tweaks and indeed messing around with the unnecessarily large number of buttons could be usefully accomplished, but for now this is fine.
Themes
Of course messing around with the appearance of a window manager is probably best dealt with using themes (if they are supported). The default configuration file I worked with included enabling beautiful via :-
require("beautiful")
beautiful.init("/usr/share/awesome/themes/default/theme.lua")
It is easier to tinker with themes with a configuration file you can edit, so I copied this theme.lua to the configuration directory named as default-theme.lua, and changed the configuration :-
-- beautiful.init("/usr/share/awesome/themes/default/theme.lua")
beautiful.init(awful.util.getdir("config") .. "/default-theme.lua")
I also removed the previous section’s font setting and set the same font within the new configuration file :-
theme.font = "LMSans10 10"
To cope with the larger font, I also increased the width of each menu item :-
theme.menu_width = "300"
Although this width does depend on having an appropriately sized screen, and not having too many levels to your menu (if it gets too wide, the extra levels don’t appear neatly).
And finally I commented out the command used to set the background … having a background image for a tiling window manager (which is designed to utilise the whole screen) is a touch unnecessary. And I don’t particularly like the default image :-
--theme.wallpaper_cmd = ...
For now I will leave the colours alone … the defaults may not be perfect but are not sufficiently irritating to spend time on right now. But the details of how to change colours of various components can be found in the theme file we have created.
Disabling Layouts
Personally I believe that you can have too much of a good thing, and choosing between the rather large number of different possible layouts that Awesome makes available is one of those. To reduce the number of possibilities, simply comment out some of the possibilities when setting the “layouts” variable in the configuration file :-
layouts =
{
awful.layout.suit.floating,
awful.layout.suit.tile,
--awful.layout.suit.tile.left,
--awful.layout.suit.tile.bottom,
--awful.layout.suit.tile.top,
awful.layout.suit.fair,
--awful.layout.suit.fair.horizontal,
awful.layout.suit.spiral,
--awful.layout.suit.spiral.dwindle,
awful.layout.suit.max,
--awful.layout.suit.max.fullscreen,
--awful.layout.suit.magnifier
}
Which you command out does not matter so much, and indeed you may very well change you mind at a later point.
A Menu
Whilst the menu built into Awesome has undoubtedly many advantages, I already have a somewhat adequate menu built up over years that relies on myGtkMenu. Whilst changing this menu could well be sensible, it does also seem sensible to keep it around during the transitional period. To do so is simply a matter of replacing certain bindings :-
-- {{{ Mouse bindings
root.buttons(awful.util.table.join(
- awful.button({ }, 3, function () mymainmenu:toggle() end),
+ --awful.button({ }, 3, function () mymainmenu:toggle() end),
+ awful.button({ }, 3, function () awful.util.spawn("/opt/bin/myGtkMenu /home/mike/lib/root.menu") end),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
))
If you hadn’t guessed, I’ve started using diffs to show the changes where it makes sense; if you cannot read diffs, this page is probably not for you.
That bit replaces the root window, but not the status bar menu :-
mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon),
- menu = mymainmenu })
+-- menu = mymainmenu })
+ command = "/opt/bin/myGtkMenu /home/mike/lib/root.menu" })
My own menu has some issues in that it doesn’t yet have anything to control awesome itself. But is good enough to get started with.
Final Word … Or Not!
And that is it! Or at least it is enough to be getting on with.