📜 ⬆️ ⬇️

XMonad + XMobar =

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:


')
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 -- Use Super instead of Alt , terminal = "urxvt" } 


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 cheatsheet

Step 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 #exec startxfce4 #exec startkde #exec gnome-session exec dbus-launch xmonad 


Useful: my .xinitrc

Now, 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 #       . ,  ,  http ! feh --bg-center http://habrastorage.org/files/c1a/90a/763/c1a90a763acc48a083a325d42f86f8ad.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 --         , startupHook = setWMName "LG3D" --    , java (IntelliJ IDEA) , borderWidth = 2 , normalBorderColor = "black" , focusedBorderColor = "orange" } myWorkspaces :: [String] myWorkspaces = ["1:web","2:dev","3:term","4:vm","5:media"] ++ map show [6..9] myLayoutHook = spacing 6 $ gaps [(U,15)] $ toggleLayouts (noBorders Full) $ smartBorders $ Mirror tiled ||| mosaic 2 [3,2] ||| tabbed shrinkText myTabConfig where tiled = Tall nmaster delta ratio nmaster = 1 delta = 3/100 ratio = 3/5 main = do xmonad defaults 


Now let's see what happened for this:


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 --         , startupHook = setWMName "LG3D" --    , java (IntelliJ IDEA) , borderWidth = 2 , manageHook = myManageHook --    , normalBorderColor = "black" , focusedBorderColor = "orange" } --     myManageHook :: ManageHook myManageHook = composeAll . concat $ [ [className =? c --> doF (W.shift "1:web") | c <- myWeb] , [className =? c --> doF (W.shift "2:dev") | c <- myDev] , [className =? c --> doF (W.shift "3:term") | c <- myTerm] , [className =? c --> doF (W.shift "4:vm") | c <- myVMs] , [manageDocks] ] where myWeb = ["Firefox","Chromium","Chrome"] myDev = ["Eclipse","Gedit","sublime-text"] myTerm = ["Terminator","xterm","urxvt"] myVMs = ["VirtualBox"] .... 


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" -- units: % , "--High" , "85" -- units: % , "--low" , "gray" , "--normal" , "darkorange" , "--high" , "darkred" , "-c" , " " , "-w" , "3" ] 10 ,Run CoreTemp [ "--template" , "<core0> <core1> <core2> <core3> <core4>°C" , "--Low" , "70" -- units: °C , "--High" , "80" -- units: °C , "--low" , "darkgreen" , "--normal" , "darkorange" , "--high" , "darkred" ] 50 ,Run StdinReader ], sepChar = "%", alignSep = "}{", template = "%StdinReader% }{ %coretemp% | %multicpu% | %memory% | %enp6s0% | %UUDD% | <fc=#FFFFCC>%date%</fc> " } 


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">#!/bin/sh vol=`amixer sget Master | grep -o -m 1 '[[:digit:]]*%' | tr -d '%'` level=`expr $vol / 10` bars=$level case $bars in 0) bar='[----------]' ;; 1) bar='[|---------]' ;; 2) bar='[||--------]' ;; 3) bar='[|||-------]' ;; 4) bar='[||||------]' ;; 5) bar='[|||||-----]' ;; 6) bar='[||||||----]' ;; 7) bar='[|||||||---]' ;; 8) bar='[||||||||--]' ;; 9) bar='[|||||||||-]' ;; 10) bar='[||||||||||]' ;; *) bar='[----!!----]' ;; esac echo $bar exit 0 


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 --      ! myKeys = [ ((mod4Mask, xK_g), goToSelected defaultGSConfig) , ((mod4Mask, xK_s), spawnSelected defaultGSConfig ["chromium","idea","gvim"]) , ((mod4Mask, xK_KP_Add), spawn "amixer set Master 10%+ && ~/.xmonad/getvolume.sh >> /tmp/.volume-pipe") , ((mod4Mask, xK_KP_Subtract), spawn "amixer set Master 10%- && ~/.xmonad/getvolume.sh >> /tmp/.volume-pipe") ] 


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.

Source: https://habr.com/ru/post/242351/


All Articles