XMonad + XMobar = ❤

Багато чули про тайловые віконні менеджери, деякі навіть чули про XMonad. А хлопці з Google навіть проміняли Unity/Gnome на XMonad. Що ж це таке, як це налаштовувати і як з цим жити? Короткий обхідний шлях для любителів кастомизировать все підряд.



Друже, нащо ж воно мені?
Для себе я виділив кілька ситуацій, коли він особливо корисний особливо корисний:

  • Робочий стіл для ноутбука розробки. Місця бракує, дуже хочеться використовувати його максимально ефективно;
  • Многопониторные робочі місця. XMonad дозволяє у всю використовувати переваги декількох мониторв з допомогою xinerma;
  • Часте переключення контекстів задач. Наприклад, розробникам часто доводиться перемикатися між IDE, файловим менеджером, консоллю і іншими інструментами. Цей процес можна прискорити;
  • Набрид візуальний шум від стандартних віконних менеджерів.


Загалом, менше слів, більше діла! Якщо хочеш управлятися з робочим оточенням так само вправно, як герой серіалу Kopps управляється з злочинцями , то ти не даремно зайшов.

Трохи про коді і прикладах
Я використовую archlinux, тому всі приклади будуть в розрізі archlinux. Але на інших лінукса всі дії проводяться схожим чином.

Всі приклади я намагався оформити у вигляді скриптів, щоб потім можна було розгорнути на новій системі. Буду залишати посилання на github.

Крок 1: Установка XMonad
Дана дія специфичено для archlinux
Перше, що потрібно зробити — це поставити yaourt, якщо він не стоїть звичайно ж. Не буду втомлювати, я роблю це скриптом install-01-yaourt.sh. (Коли знайшов на просторах інтернету, спасибі автору.)

Ставимо XMonad:

yaourt-S xmonad xmonad-contrib xmobar dmenu2

Або, якщо хочемо поставити з haskell-core репозиторію:

yaourt-S haskell-xmonad haskell-xmonad-contrib xmobar dmenu2

Так само можна поставити через yaourt darcs версію, але цей вірант ми опустимо.

Крок 2: Мінімальна настройка XMonad
Конфігурування XMonad проводиться за допомогою файлу ~/.xmonad/xmonad.hs. Як ви вже напевно здогадалися, конфігурація пишеться на Haskell.

Якщо ви не знаєте Haskell, це не біда, польюзуйтесь чужими конфіг. Коли конфіг працює, зрозуміти що до чого можна і на понятійному рівні.

Мінімальний .xmonad/xmonad.hs:

import XMonad

main = xmonad defaultConfig
{ modMask = mod4Mask -- Use Super instead of Alt
, terminal = "urxvt"
}


Курс молодого бійця з управління XMonad
При використанні тайлового віконного менеджера, вікон як таких — немає. Є тайли. Тайли ведуть себе у відповідності з поточному Layout автоматично розташовуючись так чи інакше (наприклад, Grid Layout — тупо відображає таблицой або ж Full — відобразити одне головне вікно).

Layout

Компанует тайли. За замовчуванням перемикання між Layout's виробляється з допомогою поєднання modKey+space.
У нашому випадку modKey = клавіші Windows(Super).

Тайл

Це і є ті самі, звичні нам віконця.

В Layout може бути налаштована підтримка зміни розміру тайлів і кількості майстер вікон. Так само можна «від'єднати» тайл, затиснувши кнопку modKey і потягнувши за вікно мишкою. А modKey+RightMouseButton буде змінювати розмір віконця. Перевести тайл з режиму doFloat в стандартний можна комбінацією modKey+t.

Майстер тайл — тайл, або група плиток, які будуть відображатися на самому видному місці». На скришоте в шапці, master тайл найбільший, його відразу видно.

Між тайлами можна перемикатися поєднаннями modKey+tab або modKey+j/modKey+k — фокус на попередній/наступний тайл. Так само тайли можна міняти місцями з майстер тайлом або попередніми: modKey+entеr — поміняти місцями поточний тайл і майстер тайл. modKey+J/modKey+K — поміняти місцями з наступним/попереднім

Workspace

Це по суті, робочі столи, для кожного workspace Layout свій і зберігається при перемиканні на інші робочі столи по поверненню. Хоча це поведінка можна змінити, але це вже інша історія.

Перемикатися між Wokspace можна з допомогою поєднання modKey+#, де # — номер робочого столу (не на цифровій клавіатурі).

Підіб'ємо підсумок:

modKey+tab — фокус на наступний (з шифтом на наступний);
modKey+j/modKey+k — фокус на наступний/попередній;
modKey+J/modKey+K — змінити поточний і наступний/попередній;
modKey+entеr — змінити поточний тайл і майстер тайл місцями;
modKey+m — фокус на майстер тайл;
modKey+# — робочий стіл №#;
modKey+t — перевести тайл з режиму doFloat в стандартний.

Залишу це тут: xmonad cheatsheet

Крок 3: Запуск
Є багато способів запустити XMonad, розглянемо парочку.

1. Чистий запуск
У нас встановлені тільки XMonad, нам не потрібен ні Gnome, ні KDE, ні XFCE. Ми самі по собі.
У цьому випадку для запуску достатньо налаштувати запуск xmonad у файлі ініціалізації 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


Полезняшка: мій .xinitrc

Тепер при запуску startx запустется xmonad (звичайно ж, ця команда виконується, коли ще немає X сесії).

2. Заміна поточного віконного менеджера
XMonad вміє нахабно замінювати поточний window manager. Для цього досить виконати просту команду:

xmonad --replace


3. Інтеграція з __ПодставитьЧтоНужно__
А підставити можна, наприклад, GNOME (дока для archlinux).
Тут, я думаю, кожен знайде те, що йому потрібно, ми ж рушимо до найцікавішого.

Крок 4: Ненудні шпалери
Якщо ви запустили xmonad з мінімальним конфіг, то вже, напевно, помітили, що там чорний екран. Шпалер ні!
Як же так, подумали ми, у gnome є, у kde є… І тут зробимо!

Швидко виправляємо це непорозуміння:

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 # так так, навіть так!


Вам, напевно, сподобалося, так? Можна поставити улюблену картинку з інтернету прямо на робочий стіл, зафіксуємо результат:

echo "feh --bg-center http://habrastorage.org/files/c1a/90a/763/c1a90a763acc48a083a325d42f86f8ad.jpg &">>~/.xinitrc


Крок 5: Рашпіль
Ну ось тепер можна працювати, візьмемо в руки інструмент і почнемо допілівать XMonad.

Тут можна було б прикласти конфіг і сказати — готове, але немає. Ми ж тут, щоб хоч трохи розібратися.
Попрацюємо над нашим конфіг, перетворимо його до наступного вигляду:

defaults = defaultConfig {
terminal = "urxvt"
, workspaces = myWorkspaces
, modMask = mod4Mask
, borderWidth = 2
}

myWorkspaces :: [String]
myWorkspaces = ["1:web","2:dev","3:term","4:vm","5:media"] ++ show map [6..9]

main = do
xmonad defaults


Тепер наші робочі столи з назвами, але ти, дядько Федір, цього все одно не побачиш, адже у тебе xmobar не налаштований!
Гаразд, відкладемо xmobar, зробимо щось більш суттєве:


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"] ++ show map [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


Тепер подивимося, що вийшло, для цього:

  • перекомпилим командою xmonad --recompile
  • якщо немає помилок перезапустим xmonad --restart
І, вуаля, зміни повинні вступити в силу.

Виконаємо комбінацію modKey+shift+enter. Повинно відкритися тайл з консоллю. Якщо не відкрився, можливо, проблема у рядку конфига xmonad.hs:

terminal = "urxvt"

Вкажіть термінал, які є в системі, або встановіть urxvt:


sudo pacman-S rxvt-unicode


Поєднанням modKey+p можна викликати dmenu (відкриється зверху, набираючи команду, там буде отобажен список додатків, які можна запустити). Викличемо gvim, наприклад, modKey+p> друкуємо gvim (якщо він, звичайно, є в системі) жмакаем enter.

Отже, у нас є робочі столи, тайли, лайауты… Так давайте ж автоматично направляти програми на різні робочі столи? Давайте.

Йдемо в наш конфіг xmonad.hs і додаємо наступне:

...
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"]
....


Тепер

xmonad --recompile && xmonad --restart


Через dmenu запускаємо наприклад sublime text, і ось вона! Ось вона, магія! Він одразу опинився на робочому столі з позначкою 2:dev.

Натиснемо modKey+shift+enter для запуску терміналу і, о диво! Він опиниться на 3-му робочому столі.

А як же мені дізнатися className тайла для відправки на потрібний робочий стіл?
Це дуже просто. Відкриваємо консоль, набираємо команду xprop, далі тыркаем мишкою в потрібне вікно і в консолі відобразиться інформація про нього. Нас цікавить поле WM_CLASS(STRING).
Впринципі, не обов'язково саме по className фільтрувати вікна, можна і за іншими параметрами. Можна побачити, що, наприклад, по полю title так само можна відправити віконце куди душі завгодно.
Це те, до чого ми так довго йшли…
І тут ми згадали про дядька Федора. Точніше — про xmobar. Давайте зробимо статус бар. Для тих, хто ще не зрозумів, це чорна панелька зверху (скріншот в шапці).

Крок 6: Напилок
Отже, xmobar вже повинен бути встановлений. Тому відкриваємо наш конфіг xmonad.hs і міняємо:

main = do
xmonad defaults

На:

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 of x
"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 ""

Немає часу нічого пояснювати, просто створюємо далі конфіги, а саме ~./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
,Memory Run ["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> "
}


Ух, тепер можна присісти і виконати вже знайому команду:


xmonad --recompile && xmonad --restart

Повинен був з'явиться наш довгоочікуваний бар і тепер, %USERNAME%, повинен нарешті побачити, на якому він робочому сталое знаходиться. Так само винесли заголовок поточного вікна у наш бар (прям як в mac os x, тільки гнучкіше). За це відповідає dynamicLogWithPP, який копіює інформацію в stdin xmobar, попередньо форматуємо її.

Дуже докладно про xmobar і його плагінах тут.

Будьте уважні, у font потрібно вказати що є шрифту у вашій системі. Його можна знайти у виводі команди fc-list.

Крок 7: Надфіль
Ніби все працює, але якось не затишно. Чого б ще такого зробити? Давайте зобразимо Volume Level в нашому барі! Хм, ХМобаре! Сказав — роби.

Змінюємо ~/.xmonad/xmobar.hs

Добрі люди вже написали для нас плагін PipeReader, який тупо вичитує pipe і відображає цю справу в барі.
Додамо виклик плагіна PipeReader і змінимо шаблон додавши в нього відображення гучності:

,Run PipeReader "/tmp/.volume-pipe" "vol"
template = "%StdinReader% }{ %vol% | %coretemp% | %multicpu% | %memory% | %enp6s0% | %UUDD% | <fc=#FFFFCC>%date%</fc> "


Створимо pipe

export _volume_pipe=/tmp/.volume-pipe
[[ -S $_volume_pipe ]] || mkfifo $_volume_pipe

Тепер у нас є pipe, зливаємо в нього потрібні дані. Спробуємо дізнатися рівень гучності наступною командою:

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


Приблизно так, зате швидко. Перевіряємо:

echo `~/.xmonad/getvolume.sh`>/tmp/.volume-pipe


Не знаю як у вас, а у мене працює. Але якось воно… не автоматично. Хочеться ще смачненького, а якщо хочеться, навіщо зупинятися?

Бонусні вкусняшки
Редагуємо наш ~/.xmonad/xmonad.hs.

Додамо наступне:
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") 
]


Тепер при натисканні на modKey+ -/+ (і + на NumKeyboard) буде змінюватися гучність і її рівень відразу відобразиться в нашій панельці.
Ще не заснув читач міг помітити додаткову смакоту у вигляді рядка:

((mod4Mask, xK_s), spawnSelected defaultGSConfig ["chromium","idea","gvim"])


В якості винагороди він може виконати хитру комбінацію клавіш і побачити результат.

Висновок
Хочу лише сказати, що я не претендую на якусь винятковість цього матеріалу. Так і правильним його не назвеш, напевно все можна зробити краще. Я всього лише хотів показати шлях, яким можна піти для налаштування власного оточення так, щоб цієї холодної восени на душі було тепло і приємно.

Сподіваюся, було цікаво і корисно, з радістю обговорю тематику робочого оточення, xmonad і всього, що пов'язано з Linux.

PS: Для економії місця всі приклади конфіги не забезпечені необхідними директивами import. Імпорти можна стягнути з гитхаба.

Матеріали

Сайт XMonad — багато інфи і доки за API;
Xmobar Reference — дока по Xmobar і його плагінів;
Архів конфігурацій XMonad — приклади кофнигов з відповідними картинками результату;
XMonad hotkey cheatsheet — все хоткей на одній сторінці. Для початку раджу feh --bg-center www.haskell.org/wikiupload/b/b8/Xmbindings.png;
GitHub xmonad-config — Всі конфіги, які тут використовував, в купку зібрав та на гітхабі розмістив.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.