В официальной ветке портажа стабильной является версия 3.4.15, но я решил поставить последнюю доступную — 3.5.2-r1, с USE флагом «dbus». В качество логин менеджера я выбрал SLiM. После сборки всех необходимых пакетов открываем /etc/conf.d/xdm и устанавливаем SLiM в качестве менеджера по умолчанию:
DISPLAYMANAGER="slim"
Далее необходимо сделать небольшие изменение я /etc/slim.conf
# login_cmd exec /bin/sh - ~/.xinitrc %session
login_cmd exec /bin/bash -login ~/.xinitrc %session
# login_cmd exec /bin/bash -login /usr/share/slim/Xsession %session
В этом конфиге также можете выбрать понравившуюся тему, которые лежат в /usr/share/slim/themes. Я обхожусь дефолтной. Так же там есть ещё пару интересных параметров, но я их не трогал — нет необходимости.
Терминал я решил использовать urxvt. У меня он собран:
rxvt USE="xgetdefaults"
rxvt-unicode USE="256-color focused-urgency font-styles mousewheel perl startup-notification vanilla xft"
Чтобы, собственно, запустился наш wm нужно вмести изменения в файл ~/.xinitrc (если его нету — то создать), ниже привожу свой:
urxvtd --quiet --opendisplay --fork &
pulseaudio --start &
exec ck-launch-session dbus-launch awesome
Первая строка — запускаю демон urxvt (в дальнейшем клиент вызывается urxvtc), ну, во второй понятно запускаем pulseaudio, и в последней запускаем сам awesome. Стоит отметить, что если у вас systemd, а не consolekit — то у вас вызов awesome вроде как отличается, но я не использую systemd, поэтому не берусь утверждать.
Запускаем xdm:
sudo /etc/init.d/xdm start
Логинимся и наблюдаем вот такую вот картину:
Я долго лазил по разным форумам в поисках красивых темок, конфигов, виджетов для awesome. Наткулся на такого пользователя unligic (у него много статей и интересных вещей на github)
И более новая версия его темы:
Меня это очень впечатлило и я решил поставить себе его тему — но это не увенчалось успехом. Тема просто не работало. При исправлении одной ошибки появлялась новая и т.д. Позже я увидел его пост, содержание примерно такое «ставить новичку не советую, так как там много костылей, потратите кучу времени и не факт, что заработает». Собственно так и получилось. Тогда я решил писать конфиг сам. Знаний в Lua у меня не было вообще, но гугл всегда помогает.
Конфигурационный файл лежит в /etc/xdg/awesome/rc.lua — но его я трогать не советую, просто скопируем его
cp /etc/xdg/awesome/rc.lua ~/.config/awesome/rc.lua
(У кого-то директории .config может не оказаться, не пугайтесь — просто создайте.
mkdir ~/.config
mkdir ~/.config/awesome
Начнём конфигурацию. (Да, я, пользуясь многими статьями, просто переписал его)
--------------------------------------------- --- Стандартные библиотеки --- --------------------------------------------- local gears = require("gears") local awful = require("awful") local vicious = require("vicious") awful.rules = require("awful.rules") require("awful.autofocus") local wibox = require("wibox") local beautiful = require("beautiful") local naughty = require("naughty") local menubar = require("menubar") local dbus = require("dbus")
--------------------------------------------------------- --- Устанавливаем системную локаль --- --------------------------------------------------------- os.setlocale("ru_RU.UTF-8")
-- {{{ Error handling -- Check if awesome encountered an error during startup and fell back to -- another config (This code will only ever execute for the fallback config) if awesome.startup_errors then naughty.notify({ preset = naughty.config.presets.critical, title = "Oops, there were errors during startup!", text = awesome.startup_errors }) end -- Handle runtime errors after startup do local in_error = false awesome.connect_signal("debug::error", function (err) -- Make sure we don't go into an endless error loop if in_error then return end in_error = true naughty.notify({ preset = naughty.config.presets.critical, title = "Oops, an error happened!", text = err }) in_error = false end) end -- }}}
------------------------------------- --- Устанавливаем тему --- ------------------------------------- beautiful.init("/home/worm2fed/.config/awesome/themes/worm2fed/theme.lua")
---------------------------------------------------------------------- --- Устанавливаем приложения по умолчанию --- ---------------------------------------------------------------------- terminal = "urxvtc" -- Терминал по умолчанию browser = "google-chrome-stable" -- Браузер по умолчанию editor = os.getenv("EDITOR") or "emacs" -- Редактор по умолчанию editor_cmd = terminal .. " -nw" .. editor -- Команда запуска консольного редактора
Отступы ужасно съехали, но в редакторе оно всё красиво. Клавиша модификатор — её ещё называет супер, клавиша с логотипом шиндоуса. Чаще всего это Mod4, но может и отличаться. И далее коды кнопок мыши и нужных в конфиге клавиш. Для проверки кодов мыши:
xev | grep 'button'
Для клавиши модификатора и остальных клавиш:
xev | grep 'keycode'
----------------------------------------- --- Клавиша-модификатор --- ----------------------------------------- modkey = "Mod4" --------------------------- --- Кнопки мыши --- --------------------------- left_button = 1 wheel_button = 2 right_button = 3 plus_button = 4 minus_button = 5 wheel_left_button = 6 wheel_write_button = 7 ----------------------------------- --- Скан-коды клавиш --- ----------------------------------- key_V = "#55" key_Z = "#52" key_Y = "#29" key_J = "#44" key_K = "#45" key_N = "#57" key_M = "#58" key_F = "#41" key_R = "#27" key_L = "#46" key_C = "#54" key_W = "#25" key_X = "#53" key_Q = "#24" key_H = "#43" key_Tab = "#23" key_Tilda = "#49" key_U = "#30" key_E = "#26" key_T = "#28" key_P = "#33" key_O = "#32" key_Return = "#36" key_Left = "#113" key_Right = "#114" key_Esc = "#9" key_Print = "#107" key_Alt_R = "#108" key_Alt_L = "#64" key_Space = "#65" key_Ctrl_R = "#105" key_Ctrl_L = "#37" key_Home = "#110" key_F1 = "#67" key_Mute = "#121" key_Vol_Down = "#122" key_Vol_Up = "#123"
------------------------------------------------------------------------------ --- Layouts - способы расположения окон на экране --- ----------------------------------------------------------------------------- local layouts = { awful.layout.suit.floating, -- 1 awful.layout.suit.tile, -- 2 Главное окно слева, справа второстепенные (мелкие) --awful.layout.suit.tile.left, -- * Слева второстепенные окна awful.layout.suit.tile.bottom, -- 3 Внизу второстепенные окна --awful.layout.suit.tile.top, -- * Второстепенные окна вверху awful.layout.suit.fair, -- 4 --awful.layout.suit.fair.horizontal, --awful.layout.suit.spiral, awful.layout.suit.spiral.dwindle, -- 5 awful.layout.suit.max, -- 6 --awful.layout.suit.max.fullscreen, awful.layout.suit.magnifier -- 7 }
-------------------------------------- --- Обои рабочего стола --- -------------------------------------- -- Если в теме заданы обои if beautiful.wallpaper then -- Перебираем все экраны for s = 1, screen.count() do -- На каждый экран кладем обои (можно в принципе на каждый экран свои) gears.wallpaper.maximized(beautiful.wallpaper, s, true) end end
Имена тегов могут быть абсолютно любыми — я выбрал греческие буквы — как на скрине unligic. Каждому отдельному тегу я присваиваю своё макет, которые мы определили выше.
--------------------------------------------------------- --- Тэги - виртуальные рабочие столы --- --------------------------------------------------------- -- Список тэгов tags = { -- Имена тэгов names = { " α ", " β ", " ζ ", " Θ ", " Ξ ", " ς ", " ψ "}, -- Макеты тэгов layout = { layouts[1], layouts[2], layouts[3], layouts[4], layouts[5], layouts[6], layouts[7] }} -- Перебираем все экраны for s = 1, screen.count() do -- На каждом создаем список тэгов, устанавливая макет отображения окон tags[s] = awful.tag(tags.names, s, tags.layout) end
------------------------------ --- Главное меню --- ------------------------------ --- Интернет-приложения internet_menu = { -- Формат описания пункта меню -- {<Назавание пункта меню>, <Команда запуска>, <Иконка>} {" Firefox", "firefox-bin", beautiful.firefox_icon}, {" Chrome", "google-chrome-stable", beautiful.chrome_icon}, {" Pidgin", "pidgin"} } --- editors_menu = { {" Eclipse", "eclipse-bin-4.2"}, {" Emacs", "emacs"} } --- office_menu = { {" Word", "libreoffice --writer"}, {" Exel", "libreoffice --calc"} } main_menu = awful.menu({ -- Таблица пунктов главного меню items = { {" Интернет", internet_menu}, {" Редакторы", editors_menu}, {" LibreOffice", office_menu}, {" "}, {" Перезагрузка", "reboot", beautiful.reboot_icon}, {" Выключение", "halt", beautiful.poweroff_icon}, {" Выход", awesome.quit, beautiful.logout_icon} } }) ------------------------------------------------------------------ --- Лаунчер - та кнопка что на панели слева --- ------------------------------------------------------------------ launcher = awful.widget.launcher({ image = beautiful.gentoo_icon, menu = main_menu })
-- Menubar configuration menubar.utils.terminal = terminal -- Set the terminal for applications that require it -- }}}
Тут объявляем все виджеты, которые буду использоваться. Сразу стоит отметить баг — при нажатии клавиши «отключить звук» звук исчезает, при повторном нажатии — на виджете отображает, что звук включён, но его нету. Приходится прописывать команду вручную в консоли, странно. Пока не нашёл как его исправить. И ещё смущает отображаение громкости — 90% по факту ~70 единиц в alsamixer, надо бы исправить, но никак не дойдёт руки. Ну а остальное вроде как интуитивно понятно
--------------------- --- Виджеты --- --------------------- opening_brace = '<span foreground="white" font_desc="Ubuntu">[</span>' closing_brace = '<span foreground="white" font_desc="Ubuntu">] </span>' function enbrace(str) return " "..opening_brace..str..closing_brace..' ' end function colorify(str, color) return '<span foreground="'..color..'">'..str..'</span>' end function get_colorload(val) local color = 'green' if val > 85 then color = 'red' elseif val > 60 then color = 'yellow' end return color end function format_throughput(val) if (val < 1000) then return string.format('%3dKB/s', val) elseif (val < 10240) then return string.format('%.1fMB/s', val/1024) else return string.format('%3dMB/s', val/1024) end end one_sec_timer = timer{timeout = 1} ten_sec_timer = timer{timeout = 10} spacer_big = wibox.widget.textbox() spacer_big:set_text(' ') spacer_small = wibox.widget.textbox() spacer_small:set_text(' ') volumecfg = {} volumecfg.cardid = 0 volumecfg.channel = "Master" volumecfg.widget = wibox.widget.textbox() vol_color = {} -- command must start with a space! volumecfg.mixercommand = function (command) local fd = io.popen("amixer -c " .. volumecfg.cardid .. command) local status = fd:read("*all") fd:close() local volume = string.match(status, "(%d?%d?%d)%%") volume = string.format("% 3d", volume) status = string.match(status, "%[(o[^%]]*)%]") if string.find(status, "on", 1, true) then volume = volume .. "%" vol_color="cyan" else volume = volume .. "×" vol_color = "red" end volumecfg.widget:set_markup(enbrace(colorify(volume, vol_color))) end volumecfg.update = function () volumecfg.mixercommand(" sget " .. volumecfg.channel) end volumecfg.up = function () volumecfg.mixercommand(" sset " .. volumecfg.channel .. " 1%+") end volumecfg.down = function () volumecfg.mixercommand(" sset " .. volumecfg.channel .. " 1%-") end volumecfg.toggle = function () volumecfg.mixercommand(" sset " .. volumecfg.channel .. " toggle") end volumecfg.update() client.connect_signal("manage", function (c, startup) c.size_hints_honor = false end) batterybox = wibox.widget.textbox() function battery () local io_info = io.open("/proc/acpi/battery/BAT0/info") local io_state = io.open("/proc/acpi/battery/BAT0/state") local str_info = io_info:read("*a") local str_state = io_state:read("*a") io.close(io_info) io.close(io_state) local capacity = str_info:match("last full capacity:%s+(%d+)") local current = str_state:match("remaining capacity:%s+(%d+)") local state = str_state:match("charging state:%s+(%a+)") local rate = str_state:match("present rate:%s+(%d+)") local st_color = 'green' if state == 'discharging' then st_color = 'red' elseif state == 'charging' then st_color = 'yellow' end local remain_time_str = 'inf' remain_chrg = ((current * 100) / capacity) if (('discharging' == state) and (nil ~= rate) and (rate > '0')) then remain_time = current/rate remain_time_str = string.format('%dh %.2dm', remain_time, remain_time*60%60) end local rem_color = 'red' if remain_chrg > 15 then rem_color = 'yellow' end if remain_chrg > 60 then rem_color = 'green' end batterybox:set_markup( enbrace(colorify('bat: ', 'orange') ..colorify(string.format("%d%%", remain_chrg), rem_color) ..', ' ..colorify(remain_time_str, rem_color) ..', ' ..colorify(state, st_color))) end battery() ten_sec_timer:connect_signal("timeout", battery) membox = wibox.widget.textbox() function memory() local io_meminfo = io.open("/proc/meminfo") local str_meminfo = io_meminfo:read("*a") io.close(io_meminfo) local total = str_meminfo:match("MemTotal:%s+(%d+)") local free = str_meminfo:match("MemFree:%s+(%d+)") local buffers = str_meminfo:match("Buffers:%s+(%d+)") local cached = str_meminfo:match("Cached:%s+(%d+)") local swap_total = str_meminfo:match("SwapTotal:%s+(%d+)") local swap_free = str_meminfo:match("SwapFree:%s+(%d+)") local swap_cached = str_meminfo:match("SwapCached:%s+(%d+)") local total_free = free + buffers + cached local total_swap_free = swap_free + swap_cached local p_mem = 100*(total - total_free)/total local mem_color = get_colorload(p_mem) local sw_mem = 100*(swap_total - total_swap_free)/swap_total local sw_mem_color = get_colorload(sw_mem) local p_mem = 100*(total - total_free)/total local mem_color = get_colorload(p_mem) local sw_mem = 100*(swap_total - total_swap_free)/swap_total local sw_mem_color = get_colorload(sw_mem) membox:set_markup(enbrace( colorify('mem: ', 'orange') ..colorify(string.format('%2d%%', p_mem), mem_color) ..'('..colorify(string.format('%3dMb', (total - total_free)/1024), mem_color) ..colorify(string.format('/%3dMb', (total)/1024), 'white') ..')' ..' | ' ..colorify('swap: ', 'orange') ..colorify(string.format('%2d%%', sw_mem), sw_mem_color) ..'('..colorify(string.format('%3dMb', (swap_total - total_swap_free)/1024), sw_mem_color) ..colorify(string.format('/%3dMb', (swap_total)/1024), 'white') ..')' ) ) end memory() one_sec_timer:connect_signal("timeout", memory) -- CPU usage widget cpugraph = awful.widget.graph() cpugraph:set_width(75) cpugraph:set_height(25) cpugraph:set_background_color("#494B4F") --cpugraph:set_color("#FF5656") cpugraph:set_color({ type = "horisontal", from = { 0, 0 }, to = { 0, 20 }, stops = { { 0, "#FF5656" }, { 0.5, "#88A175" }, { 1, "#AECF96" } }}) -- Register CPU widget vicious.register(cpugraph, vicious.widgets.cpu, function (widget, args) return args[1] end) cpubox = wibox.widget.textbox() cpubox_img = wibox.widget.imagebox() cpu_arr = {} cpu0_arr = {} cpu1_arr = {} for i = 0, 4 do cpu_arr[i] = 0 cpu0_arr[i] = 0 cpu1_arr[i] = 0 end function parse_cpu(cpu, stat) local cpu_new = {} local ret = {} cpu_new[0], cpu_new[1], cpu_new[2], cpu_new[3], cpu_new[4] = stat:match("cpu%d*%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)") local idle = (cpu_new[3] - cpu[3]) + (cpu_new[4] - cpu[4]) local user = (cpu_new[1] - cpu[1]) + (cpu_new[0] - cpu[0]) local system = (cpu_new[2] - cpu[2]) local total = idle + user + system local busy = user + system ret['busy'] = busy*100/total ret['sys'] = system*100/total ret['user'] = user*100/total ret['cpu'] = cpu_new return ret end function cpu() local io_stat = io.open("/proc/stat") local str_stat = io_stat:read("*l") io.close(io_stat) local ret = parse_cpu(cpu_arr, str_stat) cpu_arr = ret['cpu'] cpubox:set_markup (enbrace(colorify('cpu: ', 'orange') ..'(' ..colorify(string.format('%3d%%', ret['busy']), get_colorload(ret['busy'])) ..') | (u:' ..colorify(string.format('%3d%%', ret['user']), get_colorload(ret['user'])) ..', s:' ..colorify(string.format('%3d%%', ret['sys']), get_colorload(ret['sys'])) ..')')) end cpu() one_sec_timer:connect_signal("timeout", cpu) hddbox = wibox.widget.textbox() hdd_r = 0 hdd_w = 0 hddlist = {'/sys/block/sda/stat', '/sys/block/sdb/stat'} function hdd() local new_r = 0 local new_w = 0 for i = 1, 2 do local io_stat = io.open(hddlist[i]) local str_stat = io_stat:read("*a") io.close(io_stat) local rd, wr = str_stat:match("%s+%d+%s+%d+%s+(%d+)%s+%d+%s+%d+%s+%d+%s+(%d+)") new_w = new_w + wr new_r = new_r + rd end local r = (new_r - hdd_r)/2 local w = (new_w - hdd_w)/2 hdd_w = new_w hdd_r = new_r hddbox:set_markup ( enbrace(colorify('i/o: ', 'orange') ..'(r: ' ..colorify(format_throughput(r), 'green') ..', w:' ..colorify(format_throughput(w), 'green') ..')')) end -- RAM usage widget memwidget = awful.widget.progressbar() memwidget:set_width(30) memwidget:set_height(25) memwidget:set_vertical(true) memwidget:set_background_color('#494B4F') memwidget:set_color('#AECF96') cpugraph:set_color({ type = "linear", from = { 0, 0 }, to = { 0, 20 }, stops = { { 0, "#AECF96" }, { 0.5, "#88A175" }, { 1, "#FF5656" } }}) vicious.cache(vicious.widgets.mem) vicious.register(memwidget, vicious.widgets.mem, function (widget, args) return args[1] end, 1) --update every 13 seconds hdd() one_sec_timer:connect_signal("timeout", hdd) -- Start timers to update widgets one_sec_timer:start() ten_sec_timer:start() -- Часы и дата text_clock = awful.widget.textclock() -- Create a systray systray = wibox.widget.systray()
Статья вышла слишком большая, поэтому пришлось разбить на две части.
ссылка на оригинал статьи http://habrahabr.ru/post/214411/
Добавить комментарий