Many have heard about tile window managers, some have even heard about XMonad. And the guys from Google even
traded Unity / Gnome on XMonad. What is it, how to set it up and how to live with it? A brief workaround for those who like to customize everything.

Buddy, why is it me?
For myself, I have identified several situations where it is especially useful, especially useful:
- Desktop laptop for development. There is not enough space, I really want to use it as efficiently as possible;
- Multiple monitor jobs. XMonad allows you to take full advantage of multiple monitors with xinerma;
- Frequent task context switching. For example, a developer often has to switch between IDE, file manager, console, and other tools. This process can be accelerated;
- Tired of the visual noise from standard window managers.
')
In general, fewer words, more deeds! If you want to control the work environment as cleverly as the hero of the series Kopps manages criminals

, then you knowingly went.
A little about the code and examples
I use archlinux, so all the examples will be in the context of archlinux. But on other Linux, all actions are performed in a similar way.
I tried to arrange all the examples in the form of scripts so that I could later deploy it on the new system. I will leave links to github.
Step 1: Install XMonad
This action is specific to archlinux.The first thing to do is to put yaourt, if it is not worth it of course. I will not tire, I do it with a script
install-01-yaourt.sh . (When found on the Internet, thanks to the author.)
We put XMonad:
yaourt -S xmonad xmonad-contrib xmobar dmenu2
Or, if we want to install from the haskell-core repository:
yaourt -S haskell-xmonad haskell-xmonad-contrib xmobar dmenu2
You can also install it via yaourt darcs version, but we will omit this virant.
Step 2: Minimally configure XMonad
Configuring XMonad is done with the ~ / .xmonad / xmonad.hs file. As you may have guessed, the configuration is written in Haskell.
If you do not know Haskell, it does not matter, use other people's configs. When the config works, understand what is possible and at the conceptual level.
Minimum .xmonad / xmonad.hs:
import XMonad main = xmonad defaultConfig { modMask = mod4Mask
The course of a young fighter on the management of XMonad
When using a tile window manager, there are no windows per se. There are tiles. Tiles behave in accordance with the current Layout automatically positioning one way or another (for example, Layout Grid - stupidly displays a table or Full - display one main window).
Layout
Compiles tiles. By default, switching between Layouts `s is done using a combination of modKey + space.
In our case, modKey = Windows key (Super).
Tyle
These are the windows we are used to.
In Layout, support for resizing tiles and the number of
master windows can be configured. You can also “unplug” a tile by holding the modKey button and pulling the window with the mouse. And modKey + RightMouseButton will resize the window. You can transfer a tile from doFloat mode to standard mode using the modKey + t combination.
Master Tile - Tile, or a group of tiles that will be displayed in the "most prominent place." On the screenshot in the cap, the master tile is the largest, it is immediately visible.
Between tiles, you can switch combinations
modKey + tab or
modKey + j / modKey + k - focus on the previous / next tile. Also, tiles can be interchanged with the master tile or the previous ones:
modKey + enter - swap the current tile and master tile.
modKey + J / modKey + K - swap with the following / previous
Workspace
This is essentially the desktops, for each workspace Layout your own and saved when switching to other desktops on return. Although this behavior can be changed, this is another story.
You can switch between Wokspace using a combination of modKey + #, where # is the number of the desktop (not on the numeric keypad).
Summarize:
modKey + tab - focus on the next (or modKey + shift + tab on the previous one);
modKey + j / modKey + k - focus on the next / previous;
modKey + J / modKey + K - change current and next / previous;
modKey + enter - swap the current tile and master tile in places;
modKey + m - focus on the master tile;
modKey + # - desktop # #;
modKey + t - translate a tile from doFloat mode to standard.
Leave it here:
xmonad cheatsheetStep 3: Launch
There are many ways to run XMonad, consider a couple.
1. Clean run
We only have XMonad installed, we don’t need Gnome, KDE, or XFCE. We are on our own.
In this case, to start it is enough to configure the launch of xmonad in the system initialization file X: .xinitrc:
setxkbmap -layout "us,ru" setxkbmap -option "grp:caps_toggle,grp_led:scroll" xsetroot -cursor_name left_ptr & export PATH=~/bin:$PATH
Useful:
my .xinitrcNow, when startx starts, xmonad will start (of course, this command is executed when there is no X session yet).
2. Replacing the current window manager
XMonad can brazenly replace the current window manager. To do this, simply run a simple command:
xmonad --replace
3. Integration with __SubmitWhat you need__
And you can substitute, for example, GNOME (
dock for archlinux ).
Here, I think everyone will find what he needs, but we will move to the most interesting.
Step 4: No boring wallpapers
If you run xmonad with a minimal config, then you probably already noticed that there is a black screen. No wallpaper!
As so, we thought, there is a gnome, there is a kde ... And then we will do it!
Quickly fix this misunderstanding:
sudo pacman -S feh feh --bg-center /usr/share/backgrounds/gnome/Bokeh_Tails.jpg
You probably liked it, right? You can put your favorite picture from the Internet right on your desktop, fix the result:
echo "feh --bg-center http://habrastorage.org/files/c1a/90a/763/c1a90a763acc48a083a325d42f86f8ad.jpg &">>~/.xinitrc
Step 5: Rasp
Well, now you can work, take a tool in your hands and begin to finish XMonad.
Here you could attach a config and say - done, but no. We are here to at least a little bit to understand.
Let's work on our config, convert it to the following view:
defaults = defaultConfig { terminal = "urxvt" , workspaces = myWorkspaces , modMask = mod4Mask , borderWidth = 2 } myWorkspaces :: [String] myWorkspaces = ["1:web","2:dev","3:term","4:vm","5:media"] ++ map show [6..9] main = do xmonad defaults
Now our desktops with names, but you, Uncle Fedor, you still will not see this, because your xmobar is not configured!
Okay, let's postpone xmobar, do something more substantial:
defaults = defaultConfig { terminal = "urxvt" , workspaces = myWorkspaces , modMask = mod4Mask , layoutHook = myLayoutHook , handleEventHook = fullscreenEventHook
Now let's see what happened for this:
- re-compile with xmonad --recompile
- if there are no errors, restart xmonad --restart
And, voila, the changes should take effect.
Run the combination modKey + shift + enter. A console tile should open. If it does not open, perhaps the problem is in the xmonad.hs config line:
terminal = "urxvt"
Specify the terminal that is in the system, or install urxvt:
sudo pacman -S rxvt-unicode
With the combination
modKey + p, you can call dmenu (it will open at the top, typing a command, it will display a list of applications that can be launched). Call gvim, for example, modKey + p -> type gvim (if it is in the system, of course) click enter.
So, we have desktops, tiles, layouts ... So let's automatically send applications to different desktops? Let's.
Go to our xmonad.hs config and add the following:
... defaults = defaultConfig { terminal = "urxvt" , workspaces = myWorkspaces , modMask = mod4Mask , layoutHook = myLayoutHook , handleEventHook = fullscreenEventHook
Now
xmonad --recompile && xmonad --restart
Through dmenu we launch for example sublime-text, and here it is! Here it is magic! He immediately appeared on the desktop with a note 2: dev.
Press modKey + shift + enter to start the terminal and, lo and behold! It will be on the 3rd desktop.
And how can I find out the className of the tile to be sent to the desired desktop?
It is very simple. Open the console, type the command xprop, then type the mouse in the desired window and the console displays information about it. We are interested in the WM_CLASS (STRING) field.
In principle, it is not necessary to filter windows by className, it is possible by other parameters. You can see that, for example, in the
title field you can also send a window wherever you want.
This is what we have been walking to for so long ...
And here we remembered Uncle Fyodor. More precisely - about xmobar. Let's do the status bar. For those who still do not understand, this is the black socket on top (screenshot in the header).
Step 6: File
So xmobar should already be installed. Therefore, open our xmonad.hs config and change:
main = do xmonad defaults
On:
main = do xmproc <- spawnPipe "/usr/bin/xmobar ~/.xmonad/xmobar.hs" xmonad $ defaults { logHook = dynamicLogWithPP $ defaultPP { ppOutput = System.IO.hPutStrLn xmproc , ppTitle = xmobarColor xmobarTitleColor "" . shorten 100 , ppCurrent = xmobarColor xmobarCurrentWorkspaceColor "" . wrap "[" "]" , ppSep = " " , ppWsSep = " " , ppLayout = (\ x -> case x of "Spacing 6 Mosaic" -> "[:]" "Spacing 6 Mirror Tall" -> "[M]" "Spacing 6 Hinted Tabbed Simplest" -> "[T]" "Spacing 6 Full" -> "[ ]" _ -> x ) , ppHiddenNoWindows = showNamedWorkspaces } } where showNamedWorkspaces wsId = if any (`elem` wsId) ['a'..'z'] then pad wsId else ""
There is no time to explain anything, just create further configs, namely ~. / Xmonad / xmobar.hs:
Config { font = "xft:Droid Sans Mono:size=9:bold:antialias=true" bgColor = "#000000", fgColor = "#ffffff", position = Static { xpos = 0, ypos = 0, width = 1920, height = 16 }, lowerOnStart = True, commands = [ Run Weather "UUDD" ["-t","<tempC>°C","-L","18","-H","25","--normal","green","--high","red","--low","lightblue"] 36000 ,Run Memory ["-t","<used>/<total>M (<cache>M)","-H","8192","-L","4096","-h","#FFB6B0","-l","#CEFFAC","-n","#FFFFCC"] 10 ,Run Network "enp6s0" [ "-t" ,"rx:<rx>, tx:<tx>" ,"-H" ,"200" ,"-L" ,"10" ,"-h" ,"#FFB6B0" ,"-l" ,"#CEFFAC" ,"-n" ,"#FFFFCC" , "-c" , " " , "-w" , "2" ] 10 ,Run Date "%Y.%m.%d %H:%M:%S" "date" 10 ,Run MultiCpu [ "--template" , "<autototal>" , "--Low" , "50"
Wow, now you can sit down and execute the already familiar command:
xmonad --recompile && xmonad --restart
Our long-awaited bar should have appeared and now,% USERNAME%, should finally see what kind of working steel it is on. We also took the title of the current window to our bar (just like in mac os x, only more flexible). This is the responsibility of
dynamicLogWithPP , which copies the information into stdin xmobar, preformatting it.
In great detail about xmobar and its plugins
here .
Be careful, in the font you need to specify the existing font in your system. It can be found in the output of the fc-list command.
Step 7: File
It seems everything works, but somehow not comfortable. What else would you do? Let's display the Volume Level in our bar! Hmm, HMobare! Said - do it.
Change ~ / .xmonad / xmobar.hs
Good people have already written for us a PipeReader plugin, which stupidly reads a pipe and displays this thing in a bar.
Add a call to the PipeReader plugin and change the template by adding a volume display to it:
,Run PipeReader "/tmp/.volume-pipe" "vol" template = "%StdinReader% }{ %vol% | %coretemp% | %multicpu% | %memory% | %enp6s0% | %UUDD% | <fc=#FFFFCC>%date%</fc> "
Create pipe
export _volume_pipe=/tmp/.volume-pipe [[ -S $_volume_pipe ]] || mkfifo $_volume_pipe
Now we have a pipe, we merge the necessary data into it. Let's try to find out the volume level with the following command:
amixer sget Master | grep -o -m 1 '[[:digit:]]*%' | tr -d '%'<source> , "": <source lang="bash">echo `amixer sget Master | grep -o -m 1 '[[:digit:]]*%' | tr -d '%'`>/tmp/.volume-pipe<source> xmobar.. . ? xmobar! , . ./xmonad/getvolume.sh: <source lang="bash">
Something like this, but quickly. Checking:
echo `~/.xmonad/getvolume.sh`>/tmp/.volume-pipe
I do not know about you, but it works for me. But somehow it ... not automatically. I want more sweets, but if I want, why stop?
Bonus snacks
Edit our ~ / .xmonad / xmonad.hs.
Add the following:
defaults = defaultConfig { ... }`additionalKeys` myKeys
Now when you click on modKey + - / + (this is - and + on the NumKeyboard), the volume will change and its level will immediately appear in our panel.
A reader who has not fallen asleep might have noticed an additional tasty thing in the form of a line:
((mod4Mask, xK_s), spawnSelected defaultGSConfig ["chromium","idea","gvim"])
As a reward, he can perform a cunning key combination and see the result.
As noted in the comment, it would be nice to add a definition of the colors of the myTabConfig theme:
myTabConfig = defaultTheme { activeColor = "#6666cc" , activeBorderColor = "#000000" , inactiveColor = "#666666" , inactiveBorderColor = "#000000" , decoHeight = 10 }
Conclusion
I just want to say that I do not claim any exclusiveness of this material. And you can't call it right, for sure everything can be done better. I just wanted to show the way to go for setting up my own environment so that it was warm and pleasant for the soul in this cold autumn.
I hope it was interesting and useful, I’m happy to discuss the themes of the desktop environment, xmonad and everything related to Linux.
PS: To save space, all examples of configs are not equipped with the necessary import directives. Imports can be pulled from the githab.
Materials
Site XMonad - a lot of information and API docks;
Xmobar Reference - dock for Xmobar and its plugins;
XMonad configuration archive - examples of confections with attached result pictures;
XMonad hotkey cheatsheet - all hotkeys on one page. For a start I advise feh --bg-center
www.haskell.org/wikiupload/b/b8/Xmbindings.png;GitHub xmonad-config - All the configs that I used here, I gathered in a handful and placed it on a githaba.