Skip to content

Commit

Permalink
pactl: Do not call pactl get-* commands
Browse files Browse the repository at this point in the history
Older versions of pactl, like the one shipped by Debian Bullseye, do not
provide the get-* commands, like get-sink-volume or get-sink-mute. Work
around them by relying on `pactl list` and `pactl info` only.

This commit increases code complexity significantly and reimplementing
pactl-logic in lua impairs performance compared to a modern pactl, where
this workaround would not be needed.

Fixes issue streetturtle#390.
  • Loading branch information
Stefan Huber committed Jan 25, 2023
1 parent ef70d16 commit d727af5
Showing 1 changed file with 50 additions and 11 deletions.
61 changes: 50 additions & 11 deletions pactl-widget/pactl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,40 @@ function pactl.mute_toggle(device)
spawn('pactl set-sink-mute ' .. device .. ' toggle', false)
end

function pactl.get_default_sink()
local line = utils.popen_and_return('pactl info'):match('Default Sink: [^\n]*')
if line == nil then
return "none"
end

local t = utils.split(line, ':')
return utils.trim(t[2])
end

function pactl.get_volume(device)
local stdout = utils.popen_and_return('pactl get-sink-volume ' .. device)
if device == '@DEFAULT_SINK@' then
device = pactl.get_default_sink()
end

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
local matched_sink = false
for line in utils.popen_and_return('pactl list sinks'):gmatch('([^\r\n]*)[\r\n]') do
local linetrim = utils.trim(line)

if linetrim == "Name: " .. device then
matched_sink = true
end

if matched_sink and linetrim:match("^Volume:") then

for vol in string.gmatch(linetrim, "(%d?%d?%d)%%") do
vol = tonumber(vol)
if vol ~= nil then
volsum = volsum + vol
volcnt = volcnt + 1
end
end
break
end
end

Expand All @@ -36,12 +61,26 @@ function pactl.get_volume(device)
end

function pactl.get_mute(device)
local stdout = utils.popen_and_return('pactl get-sink-mute ' .. device)
if string.find(stdout, "yes") then
return true
else
return false

if device == '@DEFAULT_SINK@' then
device = pactl.get_default_sink()
end

local volsum, volcnt = 0, 0
local matched_sink = false
for line in utils.popen_and_return('pactl list sinks'):gmatch('([^\r\n]*)[\r\n]') do
local linetrim = utils.trim(line)

if linetrim == "Name: " .. device then
matched_sink = true
end

if matched_sink and linetrim == "Mute: yes" then
return true
end
end

return false
end

function pactl.get_sinks_and_sources()
Expand Down

0 comments on commit d727af5

Please sign in to comment.