local awful = require("awful") local gears = require("gears") local wibox = require("wibox") local awmtk = require("awmtk") local get_pactl_data = function() -- Get pactl process data and convert it into a list local pactl_processes = {} local pactl_process = io.popen("pactl list sink-inputs", "r") local pactl_data = pactl_process:read("*a") pactl_process:close() while pactl_data:match("^(%w.-\n)%w") do local test = pactl_data:match("^(%w.-\n)%w") table.insert(pactl_processes,test) pactl_data = pactl_data:gsub("^%w.-\n(%w)","%1") end table.insert(pactl_processes,pactl_data) return pactl_processes end local get_app_volume = function(pid) for key,process in pairs(get_pactl_data()) do -- Match app by pid if process:match("application.process.id = \""..tostring(pid).."\"") then return tonumber(process:match("Volume: .-(%d?%d?%d)%%")) end end -- Return nil and an error if not found matching process return nil, "Process doesn't play audio" end local set_app_volume = function(pid,percentage) for key,process in pairs(get_pactl_data()) do if process:match("application.process.id = \""..tostring(pid).."\"") then local sink_input_id = process:match("Sink Input #(%d*)") os.execute("pactl set-sink-input-volume "..sink_input_id.." "..tostring(percentage).."%") end end end return function(args) local style = awmtk.style(awmtk.defaults, args.style or {},"client_volume_") local device = args.device or "default" local icons = args.icons or { high = style.volume_icon_high, medium = style.volume_icon_medium, low = style.volume_icon_low, muted = style.volume_icon_muted, warn = style.warning_icon } local function get_icon(percent) if percent >= 66 then return icons.high elseif percent >= 33 then return icons.medium elseif percent > 0 then return icons.low else return icons.muted end end local slider = wibox.widget { widget = wibox.widget.slider, id = "widget_slider", handle_width = style.client_volume_handle_width or 6, bar_height = style.client_volumer_bar_width or 5, bar_color = style.client_volume_bar_color or "#55CC60", bar_shape = style.bar_shape, handler_shape = style.handle_shape, forced_height = 20, forced_width = 100, value = 100, } local warning_text = wibox.widget { markup = "An unknown error has occured", widget = wibox.widget.textbox } local widget = wibox.widget { { image = icons.warn, resize = true, widget = wibox.widget.imagebox, forced_height = 20, forced_width = 20 }, warning_text, spacing = style.client_volume_container_spacing_horizontal, layout = wibox.layout.fixed.horizontal } if os.execute("pactl --version") then client.connect_signal("focus",function(c) local value,err = get_app_volume(c.pid) if value then slider.value = value widget.children[2] = slider widget.children[1].image = get_icon(value) else warning_text.markup = err widget.children[2] = warning_text widget.children[1].image = icons.warn end end) slider:connect_signal("widget::redraw_needed",function() set_app_volume(client.focus.pid,slider.value) widget.children[1].image = get_icon(slider.value) end) else warning_text.markup = "pactl is not available" widget.children[2] = warning_text widget.children[1].image = icons.warn end return widget end