Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 56 additions & 28 deletions pactl-widget/pactl.lua
Original file line number Diff line number Diff line change
@@ -1,52 +1,79 @@
local spawn = require("awful.spawn")
local awful = require("awful")
local utils = require("awesome-wm-widgets.pactl-widget.utils")

local pactl = {}

-- Cached volume/mute state, updated asynchronously via update_async()
local cache = {}

-- Build a pactl argv table with the C locale forced for consistent output.
local function pactl_cmd(...)
return {'env', 'LC_ALL=C', 'pactl', ...}
end

function pactl.volume_increase(device, step)
spawn('pactl set-sink-volume ' .. device .. ' +' .. step .. '%', false)
spawn(pactl_cmd('set-sink-volume', device, '+' .. step .. '%'), false)
end

function pactl.volume_decrease(device, step)
spawn('pactl set-sink-volume ' .. device .. ' -' .. step .. '%', false)
spawn(pactl_cmd('set-sink-volume', device, '-' .. step .. '%'), false)
end

function pactl.mute_toggle(device)
spawn('pactl set-sink-mute ' .. device .. ' toggle', false)
spawn(pactl_cmd('set-sink-mute', device, 'toggle'), false)
end

function pactl.get_volume(device)
local stdout = utils.popen_and_return('pactl get-sink-volume ' .. device)

local volsum, volcnt = 0, 0
for vol in string.gmatch(stdout, "(%d?%d?%d)%%") do
vol = tonumber(vol)
if vol ~= nil then
volsum = volsum + vol
volcnt = volcnt + 1
return cache[device] and cache[device].volume
end

function pactl.get_mute(device)
return cache[device] and cache[device].mute or false
end

function pactl.update_async(device, callback)
awful.spawn.easy_async(pactl_cmd('get-sink-volume', device), function(vol_stdout, _, _, vol_exit)
if vol_exit ~= 0 then
cache[device] = nil
if callback then callback(nil, false) end
return
end
end

if volcnt == 0 then
return nil
end
if not cache[device] then cache[device] = {} end

return volsum / volcnt
end
local volsum, volcnt = 0, 0
for vol in string.gmatch(vol_stdout, "(%d?%d?%d)%%") do
vol = tonumber(vol)
if vol ~= nil then
volsum = volsum + vol
volcnt = volcnt + 1
end
end

function pactl.get_mute(device)
local stdout = utils.popen_and_return('LC_ALL=C pactl get-sink-mute ' .. device)
if string.find(stdout, "yes") then
return true
else
return false
end
if volcnt > 0 then
cache[device].volume = volsum / volcnt
end

awful.spawn.easy_async(pactl_cmd('get-sink-mute', device), function(mute_stdout, _, _, mute_exit)
if mute_exit ~= 0 then
cache[device] = nil
if callback then callback(nil, false) end
return
end
cache[device].mute = string.find(mute_stdout, "yes") ~= nil
if callback then
callback(cache[device].volume, cache[device].mute)
end
end)
end)
end

function pactl.get_sinks_and_sources()
local default_sink = utils.trim(utils.popen_and_return('pactl get-default-sink'))
local default_source = utils.trim(utils.popen_and_return('pactl get-default-source'))
local default_sink = utils.trim(utils.popen_and_return(
table.concat(pactl_cmd('get-default-sink'), ' ')))
local default_source = utils.trim(utils.popen_and_return(
table.concat(pactl_cmd('get-default-source'), ' ')))

local sinks = {}
local sources = {}
Expand All @@ -57,7 +84,8 @@ function pactl.get_sinks_and_sources()
local value
local in_section

for line in utils.popen_and_return('LC_ALL=C pactl list'):gmatch('[^\r\n]*') do
for line in utils.popen_and_return(
table.concat(pactl_cmd('list'), ' ')):gmatch('[^\r\n]*') do

if string.match(line, '^%a+ #') then
in_section = nil
Expand Down Expand Up @@ -117,7 +145,7 @@ function pactl.get_sinks_and_sources()
end

function pactl.set_default(type, name)
spawn('pactl set-default-' .. type .. ' "' .. name .. '"', false)
spawn(pactl_cmd('set-default-' .. type, name), false)
end


Expand Down
40 changes: 25 additions & 15 deletions pactl-widget/volume.lua
Original file line number Diff line number Diff line change
Expand Up @@ -166,31 +166,40 @@ local function worker(user_args)
end

local function update_graphic(widget)
local vol = pactl.get_volume(device)
if vol ~= nil then
widget:set_volume_level(vol)
end

if pactl.get_mute(device) then
widget:mute()
else
widget:unmute()
end
pactl.update_async(device, function(vol, is_muted)
if vol ~= nil then
widget:set_volume_level(vol)
end
if is_muted then
widget:mute()
else
widget:unmute()
end
end)
end

function volume:inc(s)
pactl.volume_increase(device, s or step)
update_graphic(volume.widget)
gears.timer.start_new(0.1, function()
update_graphic(volume.widget)
return false
end)
end

function volume:dec(s)
pactl.volume_decrease(device, s or step)
update_graphic(volume.widget)
gears.timer.start_new(0.1, function()
update_graphic(volume.widget)
return false
end)
end

function volume:toggle()
pactl.mute_toggle(device)
update_graphic(volume.widget)
gears.timer.start_new(0.1, function()
update_graphic(volume.widget)
return false
end)
end

function volume:popup()
Expand Down Expand Up @@ -218,7 +227,7 @@ local function worker(user_args)
)
)

gears.timer {
local volume_timer = gears.timer {
timeout = refresh_rate,
call_now = true,
autostart = true,
Expand All @@ -231,7 +240,8 @@ local function worker(user_args)
awful.tooltip {
objects = { volume.widget },
timer_function = function()
return pactl.get_volume(device) .. " %"
local vol = pactl.get_volume(device)
return (vol and string.format("%.0f", vol) or "?") .. " %"
end,
}
end
Expand Down