Showing posts with label window manager. Show all posts
Showing posts with label window manager. Show all posts

Thursday, 13 September 2012

Awesome WM Reloaded!

I have been playing around with plenty of tiling window managers and until now none of them worked as I wanted. Finally I have succeeded to set up Awesome WM to meet all my needs but I really had to work hard to get to this point. I cannot go further without mentioning the dark sides of Awesome: things are just not working as they are written, sample config files are unfunctional, modules and config scripts are far not compatible with each other, AUR packages are sometimes simply not installable. For example I cannot use bashets because it just does not work on my system although I use the sample config file coming with the latest bashet release. I tried to upgrade my stable awesome to awesome-git from AUR but I could not manage to do it, yaourt complains about a non-existent(!) package as a dependency:
error: target not found: xcb-util-image 
What is this all around? Why is it so difficult?
(UPDATE: xcb-util problem is solved by now, thanks to the package maintainers!).


OK, now the awesome part of awesome and the workarounds for some issues:

Installation:

I installed these packages:
  • awesome (3.4.13-1),  community repository 
  • vicious (2.1.0-1),  community repository
  • shifty-github (20120913-1), AUR
  • awesome-scratchpad-git (20120913-1), (optional, if you need a scratchpad), AUR
Configuration tips:

See my rc.lua, it works nicely with the above-mentioned software versions.


Changed "require" format:

From Lua 5.1 the way you have to load modules in your rc.lua has changed:

Older format:
require("vicious")

New format:
vicious = require("vicious")

Vicious, for example will not work with the older format!


Raise clients on tag switching:

Add this line to your rc.lua:

require("awful.autofocus")
If you do not do this, navigating between tags will not focus the clients which is quite annoying in my opinion.


Run or raise:
If you want to have only one instance of certain applications you can place a small code to the end of your rc.lua for defining the run_or_raise function. You can read more on this here. After this you can define your key bindings to run something only once like this:

awful.key({ modkey,}, "f", function () run_or_raise("firefox", { class = "Firefox" }) end),

As a result of this example when you press MOD+f firefox will start or if there is already an existing window with WM_CLASS="Firefox" running that window will gain focus.


Skype - as usual - needs special attention when you deal with window management. Run_or_raise will start a new instance of skype if it is already sitting in your systray. To prevent it you can write a script that examines if skype is already running. My skypestart script looks like this:

 if [ "$(pgrep skype)" ]
  then
     echo skype is already running
  else
     skype
fi

And the appropriate rc.lua line for the binding is:

awful.key({ modkey,}, "s", function () run_or_raise("<your path>/skypestart", { name = "Skype" }) end),


Use your custom theme:
beautiful.init(".config/awesome/themes/<your_theme_dir>/theme.lua")

See my theme.lua.

Custom statusbar script using vicious:
You can set up a shell script to create a status message for your status bar. This script can contain colour codes to have a nicer output. For example I write the battery percentage with red when its value is under 30% instead of the normal orange colour. My bar looks like this:


My status.sh script to generate this output:


span_hi='<span color="#ff8700">'   #colour for normal battery
span_lo='<span color="#aaaaaa">'     #colour for normal battery
span_sep='<span color="#ff8700">'  #colour for normal battery
span_warn='<span color="#ff0000">'

## Set battery message (works on Thinkpad Edge 11 with tp_smapi driver)

batt=`cat /sys/devices/platform/smapi/BAT0/remaining_percent`
if (($batt <= 30));
then battstate=$span_warn$batt'%% </span>'$span_lo`cat /sys/devices/platform/smapi/BAT0/state`'</span>'
else battstate=$span_hi$batt'%% </span>'$span_lo`cat /sys/devices/platform/smapi/BAT0/state`'</span>'
fi

## Create the output

echo ' '$battstate$span_sep' | </span>'$span_lo`cat /proc/cpuinfo | grep "cpu MHz" | awk '{sum+=$4} END { print sum/NR,"MHz"}'`'</span>'$span_sep' | </span>'$span_lo`date "+%a, %Y.%m.%d."`' - </span>'$span_hi`date +"%R"`' </span>'

I initialise this status script from my rc.lua with vicious which upgrades the status bar every 10 seconds:

statwidget = widget({
   type = 'textbox',
   name = 'statwidget'
})

function run_script()
    local filedescriptor = io.popen("/<path>/<to>/<your>/status.sh")
    local value = filedescriptor:read()
    filedescriptor:close()
    return {value}
end
vicious.register(statwidget, run_script, '$1', 10)


And I call the vicious widget wen I construct my top bar later in rc.lua:

    topbar[s].widgets = {
        {
            mytaglist[s],
            mypromptbox[s],
            layout = awful.widget.layout.horizontal.leftright
        },
        mylayoutbox[s],
        s == 1 and mysystray or nil,
        statwidget,
        mytasklist[s],
        layout = awful.widget.layout.horizontal.rightleft
        }

Scratchpad calculator:
It is good to have a calculator at hand in a floating window. The scratchpad is an easy way to pop up a floating window on the actual screen. You can also set the default geometry of the window so it will always show up with the same size and place. With a key binding you can pop up or hide this window.


For this you need to install a calculator, I use qalculate-gtk. You also need  the awesome-scratchpad-git AUR package and some configuration in rc.lua:

-------libraries section------
require("scratch")
------globalkeys section------
 -- Binding for calculator in scratchpad
awful.key({ modkey }, "q", function () scratch.drop("qalculate","top","center",250,300) end),

If you need a calculator you can pop it up any time with Mod+q. When you do not need it simply hide it with the same binding.


Tip: How to take screenshots?
You need scrot, sxiv and xfe installed for this to work. Place this line to your rc.lua globalkeys section:

awful.key({ }, "Print",  function () awful.util.spawn_with_shell("scrot -e 'mv $f ~/Desktop/ 2>/dev/null && xfe ~/Desktop/ & sleep 1 && sxiv ~/Desktop/$f'") end),

Your PrintScreen key will take a screenshot and pop it up in an sxiv image viewer window and also in an xfe file manager window for further use.


Dual screen and VGA hotplugging
One of the major benefits of Awesome is that it can handle a dual head setup quite flawlessly and in an easy-to-configure manner. When you attach or detach displays in your system you can redistribute your clients between your actual monitors by means of a simple keystroke. First you need to install xrandr to fulfil this task. Xinerama might be supported as well, I did not test it with Awesome.

A simple script using xrandr can be handy to make the changes easy. I have a laptop with an LCD panel (LVDS1) and some connectors (VGA1, HDMI1, DP1) where other displays can be attached to the system. My dual_screen script examines if an external display is attached to any of these ports and if it finds one it will make that one a primary display and sets the LVDS1 to be the secondary one placed on the left hand side of the primary display.
If it does not find any attached monitors it will set LVDS to be the one and only, primary display. My .xinitrc and dual-screen scripts to configure dual head setup can be found here.

By running the dual_screen script and restarting Awesome the clients will be arranged according to the rules of your rc.lua.

I placed a key binding to the global keys of my rc.lua to do this on a keystroke:

-- VGA hotplugging and restarting awesome. The dual-screen bash script runs an xrandr screen setup.
    awful.key({ modkey, "Control"}, "r",
        function ()
        awful.util.spawn_with_shell("/dev/shm/scripts/dual-screen")
        awesome.restart()
        end),

And according to my Shifty rules in my rc.lua there are clients to be placed on screen 1 (primary screen) and others on screen 2 (secondary screen). If there is only one screen then Awesome will place all clients on the primary screen.


And the results


 



Friday, 23 September 2011

Tiling window managers

My first try with tiling window managers was ion3. I liked it and used it for months. I loved its keystroke-driven minimalistic approach. Although the Lua config was too high for me, I could not set things up correctly. It did not support fancy titlebars nor a systray, it simply worked. I saw its limitations and I was a bit sad that the developers did not support the software any more, so I went back to Gnome. Nowadays as I started using Arch Linux I needed something powerful and tiling WMs came to my mind again. So I made some research and tried some of them. Here is my short review of them.
 
 The WM I need is a tiling window manager with:
- Configurable keyboard shortcuts
- Tag bar (to see which tag I actually use), urgent tag is preferred
- Systray
- Statusbar (with configurable contents of computer state like clock, cpu, battery, etc.)
- Easy-to-use config file (I do not want to learn programming languages to set it up!)
- Dual-head support
- Rules to place different applications where (screen and workspace) I want and how (floating or tiling) I want.

Here are the ones I tried:

Awesome
Awesome is simply awesome. It has almost everything I need: It handles dual screen (although it was sort of a pain to set it up and still I have problems with it), there is a built-in taskbar and systray: good point! The lua configuration language is too diificult for me. I just do not see logics and simplicity here, there are redundant solutions for things and above all the config syntax changes from one version of Awesome to another. Maybe I will come back later again.

Subtle
Subtle is an easy-to-set-up tiling WM but I could not get dual head working on it properly. Possibly it is my fault, I did not spend too much time with it.

Xmonad
At first sight I liked it but it has a frightening config file written in Haskell and you have to load third-party plugins to access basic features (like statusbar, systray, etc.).

i3
i3 is very close to my expectations. I only have one complaint against it: it does not support a configurable statusbar (although it has a built-in one, it contains too much and useless information but others are missing) nor a native systray. Somehow I could not get third-party statusbars and systrays working in my dual head setup. They always overlapped, windows were ignoring them, etc. I might have done dirty hacks to get it work but I gave it up. Anyway, nice project.

Scrotwm
Simple, very easy to configure but lacks major features like tags and rules.

Wmfs
After quite a lot of experimenting with so much WMs out there I found Wmfs. It has a very straightforward configuration file and you do not have to include plugins or third-party software. Multi-head setup works very well and can be set up as easily as everything else. The "bar" contains a taglist, a layout chooser, the title of the actual window, a message where you can place any text with some formatting (i.e. a static text or a status message updated regularly by a shell script) and a systray. Everything can be driven by keystrokes and rules can be assigned to many different window properties. This is the first tiling WM that I could set up properly with one simple(!) config file and it just works fine with all the main features I expected. I have some minor issues though:
- If I run xrandr, the system crashes. This means that hot-changing of single / dual monitors does not work. For example if I plug in an external display to my laptop and run xrandr to set my dual screen up, all my running applications are killed and the WM hangs. Maybe there will be a solution for this soon, but by that time I have to be careful with this.

- The titlebar shows only the title of the actual window. Right clicking shows the other clients of the actual tag but it is not convenient to use. A bar with all the windows of the actual tag would be nice with color mark for the actual client (just like in Awesome). This is not a major issue but it would be very informative to have such a feature.
- Using regexps or wildcards in rule definitions would be very handy. This is a nice-to-have feature, I can live without it.

My Wmfs dual-head GUI looks like this:



You can find my actual wmfsrc config file, wmfs-status message generator script (for indicating the date, time, battery and processor state invoked from .xinitrc regularly) and my .xinitrc file in the right panel under "My actual config files".