Тут объявляем все виджеты, которые буду использоваться. Сразу стоит отметить баг — при нажатии клавиши «отключить звук» звук исчезает, при повторном нажатии — на виджете отображает, что звук включён, но его нету. Приходится прописывать команду вручную в консоли, странно. Пока не нашёл как его исправить. И ещё смущает отображаение громкости — 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()
Знаю, что верхнюю и нижнюю панель можно было создать вместе, а не разделять, и так наверное было бы даже грамотнее, но у меня руки не доходят переписать. Собственно в этой части мы создаём теги и отображаем виджеты.
-------------------------------------------------- --- Декларируем список тэгов #1 --- -------------------------------------------------- main_wibox = {} prompt_box = {} layout_box = {} tag_list = {} -- Задаем обработку кнопок мыши для списка тегов tag_list.buttons = awful.util.table.join( -- Отобразить тэг awful.button({ }, left_button, awful.tag.viewonly ), -- Переместить клиент на данный тэг awful.button({ modkey }, left_button, awful.client.movetotag ), -- Отобразить выбранный тэг вместе с текущим awful.button({ }, right_button, awful.tag.viewtoggle ), -- Отобразить текущий клиент в текущем и выбранном тэге awful.button({ modkey }, right_button, awful.client.toggletag ), -- Следующий тэг awful.button({ }, plus_button, function(t) awful.tag.viewnext(awful.tag.getscreen(t)) end ), -- Предыдущий тэг awful.button({ }, minus_button, function(t) awful.tag.viewprev(awful.tag.getscreen(t)) end ) ) --------------------------------------------------- --- Декларируем список задач #1 --- --------------------------------------------------- -- Задаем обработку кнопок мыши для списка задач task_list = {} task_list.buttons = awful.util.table.join( -- Левая кнопка awful.button({ }, left_button, function(c) -- Если клиент имеет фокус - свернуть его if c == client.focus then c.minimized = true else -- Иначе, передать фокус на клиент не сворачивая c.minimized = false -- и ещё вот эта хрень, назначение которой мне пока не ясно if not c:isvisible() then awful.tag.viewonly(c:tags()[1]) end client.focus = c c:raise() end end), -- Щелчок правой кнопкой awful.button({ }, right_button, function(c) if instance then instance:hide() instance = nil else instance = awful.menu.clients({ width=250 }) end end), -- Сместить фокус на следующее окно awful.button({ }, plus_button, function () awful.client.focus.byidx(1) if client.focus then client.focus:raise() end end), -- Сместить фокус на предыдущее окно awful.button({ }, minus_button, function() awful.client.focus.byidx(-1) if client.focus then client.focus:raise() end end) ) -------------------------------------------------------------------------- --- Создаем для каждого экрана панель задач #1 --- --------------------------------------------------------------------------- -- Цикл, перебирающий все экраны for s = 1, screen.count() do -- Список тэгов: передаем номер экрана, и назначения кнопок мыши tag_list[s] = awful.widget.taglist(s, awful.widget.taglist.filter.all, tag_list.buttons) -- Список запущенных задач: передаем номер экрана, и назначения кнопок мыши task_list[s] = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, task_list.buttons) -- Контейнер для всех виджетов - наша панель задач -- расположенная внизу экрана номер s и шириной main_wibox[s] = awful.wibox({ position = "top", height = "28", screen = s }) -- Создаем виджеты расположенные слева (левый блок виджетов) local left_layout = wibox.layout.fixed.horizontal() -- Добавляем на левый блок виджетов последовательно left_layout:add(launcher) -- лаунчер (кнопка главного меню) left_layout:add(tag_list[s]) -- список тэгов -- Создаем виджеты расположенные справа local right_layout = wibox.layout.fixed.horizontal() -- Системный трей делаем почему-то только на первом экране, взято из стандартного конфига if s == 1 then right_layout:add(wibox.widget.systray()) end -- Добавляем right_layout:add(volumecfg.widget) right_layout:add(text_clock) -- Текстовые часы -- Создаем контейнер для всей панели задач local layout = wibox.layout.align.horizontal() layout:set_left(left_layout) layout:set_middle(task_list[s]) layout:set_right(right_layout) main_wibox[s]:set_widget(layout) end -------------------------------------------------- --- Декларируем список тэгов #2 --- -------------------------------------------------- bottom_wibox = {} bottom_prompt_box = {} botton_layout_box = {} --------------------------------------------------------------------------- --- Создаем для каждого экрана панель задач #2 --- --------------------------------------------------------------------------- -- Цикл, перебирающий все экраны for s = 1, screen.count() do -- Кнопка переключения макетов расположения окон layout_box[s] = awful.widget.layoutbox(s) -- декларируем для неё назначения кнопок мыши layout_box[s]:buttons(awful.util.table.join( -- Переключить на макет вперед awful.button({ }, left_button, function () awful.layout.inc(layouts, 1) end), -- Переключить на макет назад awful.button({ }, right_button, function () awful.layout.inc(layouts, -1) end) ) ) -- Командная строка - виджет реализующий командную строку на панели задач bottom_prompt_box[s] = awful.widget.prompt() -- Контейнер для всех виджетов - наша панель задач -- расположенная внизу экрана номер s и шириной в px bottom_wibox[s] = awful.wibox({ position = "bottom", height = "25", screen = s }) -- Создаем виджеты расположенные слева (левый блок виджетов) local l_layout = wibox.layout.fixed.horizontal() -- Добавляем на левый блок виджетов последовательно l_layout:add(bottom_prompt_box[s]) -- командную строку l_layout:add(spacer_small) -- otstup l_layout:add(cpubox) l_layout:add(cpugraph) l_layout:add(spacer_small) l_layout:add(membox) l_layout:add(memwidget) -- Создаем виджеты расположенные справа local r_layout = wibox.layout.fixed.horizontal() r_layout:add(hddbox) r_layout:add(spacer_small) r_layout:add(batterybox) r_layout:add(spacer_small) r_layout:add(layout_box[s]) -- Кнопку переключения макетов -- Создаем контейнер для всей панели задач local lay = wibox.layout.align.horizontal() lay:set_left(l_layout) --lay:set_middle() lay:set_right(r_layout) bottom_wibox[s]:set_widget(lay) end
ссылка на оригинал статьи http://habrahabr.ru/post/214467/
Добавить комментарий