Created system volume class
parent
fca8c4bbd5
commit
c37ea71746
|
@ -1,7 +1,7 @@
|
|||
return gears.table.join(
|
||||
awful.key( {}, "XF86AudioRaiseVolume",
|
||||
function ()
|
||||
wrapper.volume.up()
|
||||
vol:up()
|
||||
end,
|
||||
{
|
||||
description = "Volume up",
|
||||
|
@ -11,7 +11,7 @@ return gears.table.join(
|
|||
|
||||
awful.key( {}, "XF86AudioLowerVolume",
|
||||
function ()
|
||||
wrapper.volume.down()
|
||||
vol:down()
|
||||
end,
|
||||
{
|
||||
description = "Volume down",
|
||||
|
@ -21,7 +21,7 @@ return gears.table.join(
|
|||
|
||||
awful.key( {}, "XF86AudioMute",
|
||||
function ()
|
||||
wrapper.volume.togglemute()
|
||||
vol:togglemute()
|
||||
end,
|
||||
{
|
||||
description = "Mute",
|
||||
|
|
|
@ -10,7 +10,6 @@ local desktop = {
|
|||
textclock = require("desktop.widgets.textclock"),
|
||||
layoutbox = require("desktop.widgets.layoutbox"),
|
||||
keymap = require("desktop.widgets.keymap"),
|
||||
volume = require("desktop.widgets.volume"),
|
||||
tagindicator = require("desktop.widgets.tagindicator"),
|
||||
launcher = require("desktop.widgets.launcher"),
|
||||
shortcut = require("desktop.widgets.shortcut"),
|
||||
|
@ -185,7 +184,7 @@ awful.screen.connect_for_each_screen(
|
|||
|
||||
desktop.widgets.battery,
|
||||
desktop.widgets.backlight,
|
||||
desktop.widgets.volume,
|
||||
vol.widget.widget,
|
||||
desktop.widgets.space(8),
|
||||
|
||||
desktop.widgets.keymap,
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
local widget = {}
|
||||
|
||||
|
||||
widget.icon = wibox.widget {
|
||||
resize = true,
|
||||
image = beautiful.icons.volume.mute,
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
widget.arc = wibox.widget {
|
||||
{
|
||||
widget.icon,
|
||||
top = beautiful.dpi(1),
|
||||
bottom = beautiful.dpi(1),
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
max_value = 1,
|
||||
thickness = beautiful.dpi(4),
|
||||
start_angle = 4.71238898, -- 2pi*3/4
|
||||
--forced_height = beautiful.dpi(16),
|
||||
--forced_width = beautiful.dpi(16),
|
||||
colors = {"#27D4CC", "#00446B"},
|
||||
bg = "#FFFFFF30",
|
||||
paddings = beautiful.dpi(2),
|
||||
widget = wibox.container.arcchart
|
||||
}
|
||||
|
||||
widget.bar = wibox.widget {
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
--forced_height = 20,
|
||||
forced_width = beautiful.dpi(50),
|
||||
paddings = 0,
|
||||
border_width = 0,
|
||||
color = {
|
||||
type = "linear",
|
||||
from = {0, 0}, to = {beautiful.dpi(50), 0},
|
||||
stops = { { 0, "#27D4CC" }, { 1, "#00446B" }}
|
||||
},
|
||||
background_color = "#FFFFFF30",
|
||||
widget = wibox.widget.progressbar,
|
||||
shape = gears.shape.rounded_bar,
|
||||
}
|
||||
|
||||
|
||||
widget.widget = wibox.widget {
|
||||
{
|
||||
{ -- Right space
|
||||
widget = wibox.widget.separator,
|
||||
color = beautiful.color.transparent,
|
||||
forced_width = beautiful.dpi(3)
|
||||
},
|
||||
{
|
||||
widget.arc,
|
||||
top = beautiful.dpi(2),
|
||||
bottom = beautiful.dpi(2),
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
{ -- Left space
|
||||
widget = wibox.widget.separator,
|
||||
color = beautiful.color.transparent,
|
||||
forced_width = beautiful.dpi(3)
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
layout = wibox.container.background,
|
||||
}
|
||||
|
||||
widget.widget:connect_signal("mouse::enter", function(result)
|
||||
widget.widget.bg = beautiful.color.bar.hover_bg
|
||||
|
||||
end)
|
||||
|
||||
widget.widget:connect_signal("mouse::leave", function(result)
|
||||
widget.widget.bg = beautiful.color.transparent
|
||||
end)
|
||||
|
||||
widget.widget:connect_signal("button::press",
|
||||
function(_, _, _, button, mods)
|
||||
|
||||
-- Right-click
|
||||
if (button == 3) then
|
||||
wrapper.volume.togglemute()
|
||||
|
||||
-- Scroll up
|
||||
elseif (button == 4) then
|
||||
wrapper.volume.up()
|
||||
|
||||
-- Scroll down
|
||||
elseif (button == 5) then
|
||||
wrapper.volume.down()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
widget.update = function(status)
|
||||
|
||||
if (status.value == false) then
|
||||
widget.icon.image = beautiful.icons.volume.error
|
||||
widget.arc.value = 100;
|
||||
widget.bar.value = 100;
|
||||
return
|
||||
end
|
||||
|
||||
widget.arc.value = status.value / 100;
|
||||
widget.bar.value = status.value;
|
||||
|
||||
|
||||
if (status.mute) then
|
||||
-- Set muted icon
|
||||
widget.icon.image = beautiful.icons.volume.mute
|
||||
else
|
||||
-- Set icon by value
|
||||
if status.value > 70 then
|
||||
widget.icon.image = beautiful.icons.volume.high
|
||||
elseif status.value > 40 then
|
||||
widget.icon.image = beautiful.icons.volume.medium
|
||||
elseif status.value > 0 then
|
||||
widget.icon.image = beautiful.icons.volume.low
|
||||
elseif status.value == 0 then
|
||||
widget.icon.image = beautiful.icons.volume.off
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Add various hooks
|
||||
|
||||
wrapper.volume.add_hook(widget.update)
|
||||
wrapper.volume.commands:watch(
|
||||
5,
|
||||
function()
|
||||
wrapper.volume.commands:get(widget.update)
|
||||
end,
|
||||
widget.widget
|
||||
)
|
||||
|
||||
-- Update volume widget at start
|
||||
wrapper.volume.commands:get(widget.update)
|
||||
|
||||
return widget.widget
|
7
rc.lua
7
rc.lua
|
@ -7,6 +7,7 @@ naughty = require("naughty")
|
|||
beautiful = require("beautiful")
|
||||
menubar = require("menubar")
|
||||
wibox = require("wibox")
|
||||
|
||||
configuration_dir = gears.filesystem.get_configuration_dir()
|
||||
require("awful.autofocus")
|
||||
|
||||
|
@ -33,8 +34,14 @@ wrapper.ibus.set(1)
|
|||
|
||||
beautiful.init(require("theme"))
|
||||
|
||||
-- Initialize volume controller
|
||||
volume = require("volume")
|
||||
vol = volume:new{pa_sink = conf.pamixer_sink}
|
||||
|
||||
desktop = require("desktop")
|
||||
|
||||
|
||||
|
||||
--------------
|
||||
-- Autostart--
|
||||
--------------
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
local P = require("volume/volume")
|
||||
return P
|
|
@ -0,0 +1,203 @@
|
|||
local volume_widget = require("volume/widget")
|
||||
local P = {}
|
||||
|
||||
---
|
||||
-- Internal methods
|
||||
---
|
||||
function P:_full_args()
|
||||
-- Build complete pamixer arguments, combining sink and options.
|
||||
-- Must have a leading space.
|
||||
if (self.pa_sink == "") then
|
||||
return " " .. self.pa_options
|
||||
else
|
||||
return " --sink" .. self.pa_sink .. " " .. self.pa_options
|
||||
end
|
||||
end
|
||||
|
||||
function P:_get_status()
|
||||
-- Update mute status and volume.
|
||||
-- Values in this table are updated.
|
||||
awful.spawn.easy_async(
|
||||
"pamixer --get-mute --get-volume" .. self:_full_args(),
|
||||
function(stdout, stderr, exitreason, exitcode)
|
||||
|
||||
-- Get mute state
|
||||
local muted = string.match(stdout, "(%w%w%w%w%w?) ")
|
||||
self.muted = (muted == "true")
|
||||
|
||||
local value = string.match(stdout, "(%d?%d?%d)") -- (\d?\d?\d)\%)
|
||||
|
||||
if (value == nil) then
|
||||
self.volume = nil
|
||||
self.ready = false
|
||||
else
|
||||
self.volume = tonumber(string.format("% 3d", value))
|
||||
self.ready = true
|
||||
end
|
||||
|
||||
self:_update_widget()
|
||||
end
|
||||
)
|
||||
|
||||
-- This is used inside a timer, so return true to keep it running.
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
function P:_update_widget()
|
||||
if (not self.ready) then
|
||||
self.widget.icon.image = beautiful.icons.volume.error
|
||||
self.widget.arc.value = 100;
|
||||
self.widget.bar.value = 100;
|
||||
return
|
||||
end
|
||||
|
||||
self.widget.arc.value = self.volume / 100;
|
||||
--self.widget.bar.value = self.volume;
|
||||
|
||||
|
||||
if (self.muted) then
|
||||
-- Set muted icon
|
||||
self.widget.icon.image = beautiful.icons.volume.mute
|
||||
else
|
||||
-- Set icon by value
|
||||
if self.volume > 70 then
|
||||
self.widget.icon.image = beautiful.icons.volume.high
|
||||
elseif self.volume > 40 then
|
||||
self.widget.icon.image = beautiful.icons.volume.medium
|
||||
elseif self.volume > 0 then
|
||||
self.widget.icon.image = beautiful.icons.volume.low
|
||||
elseif self.volume == 0 then
|
||||
self.widget.icon.image = beautiful.icons.volume.off
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
-- Simple actions
|
||||
---
|
||||
function P:volume_up()
|
||||
if (not self.ready) then
|
||||
return
|
||||
end
|
||||
|
||||
if self.muted then
|
||||
self:unmute()
|
||||
end
|
||||
|
||||
awful.spawn("pamixer --increase 5" .. self:_full_args(), false)
|
||||
wrapper.sound.play("volume_up")
|
||||
self.volume = self.volume + 5
|
||||
self:_update_widget()
|
||||
end
|
||||
|
||||
function P:volume_down()
|
||||
if (not self.ready) then
|
||||
return
|
||||
end
|
||||
|
||||
if self.muted then
|
||||
self:unmute()
|
||||
end
|
||||
|
||||
awful.spawn("pamixer --decrease 5" .. self:_full_args(), false)
|
||||
wrapper.sound.play("volume_down")
|
||||
self.volume = self.volume - 5
|
||||
self:_update_widget()
|
||||
end
|
||||
|
||||
function P:volume_set(value)
|
||||
if (not self.ready) then
|
||||
return
|
||||
end
|
||||
|
||||
if self.muted then
|
||||
self:unmute()
|
||||
end
|
||||
|
||||
awful.spawn("pamixer --set_volume " .. tostring(value) .. self:_full_args(), false)
|
||||
self.volume = value
|
||||
self:_update_widget()
|
||||
end
|
||||
|
||||
function P:mute()
|
||||
if (not self.ready) then
|
||||
return
|
||||
end
|
||||
|
||||
self.muted = true
|
||||
awful.spawn("pamixer --mute" .. self:_full_args(), false)
|
||||
v:_update_widget()
|
||||
end
|
||||
|
||||
function P:unmute()
|
||||
if (not self.ready) then
|
||||
return
|
||||
end
|
||||
|
||||
self.muted = false
|
||||
awful.spawn("pamixer --unmute" .. self:_full_args(), false)
|
||||
self:_update_widget()
|
||||
end
|
||||
|
||||
function P:toggle_mute()
|
||||
if (not self.ready) then
|
||||
return
|
||||
end
|
||||
|
||||
if self.muted then
|
||||
self:unmute()
|
||||
else
|
||||
self:mute()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Create new volume_interface
|
||||
---
|
||||
function P:new(args)
|
||||
-- Arguments
|
||||
v = {
|
||||
pa_options = args.cli_options or "",
|
||||
pa_sink = args.pa_sink or "",
|
||||
update_interval = args.update_interal or 1,
|
||||
ready = false, -- is all the information in this class up-to-date?
|
||||
-- if this is false, ui will show an error and most methods will
|
||||
-- do nothing. Updated in _get_status()
|
||||
}
|
||||
|
||||
-- Create widget for this volume interface
|
||||
v.widget = volume_widget.new()
|
||||
|
||||
-- Attach button press signals
|
||||
v.widget.widget:connect_signal("button::press",
|
||||
function(_, _, _, button, mods)
|
||||
if (button == 3) then -- Right-click
|
||||
v:toggle_mute()
|
||||
elseif (button == 4) then -- Scroll up
|
||||
v:volume_up()
|
||||
elseif (button == 5) then -- Scroll down
|
||||
v:volume_down()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
setmetatable(v, self)
|
||||
self.__index = self
|
||||
|
||||
-- This timer keeps mute and volume status up-to-date.
|
||||
v.timer = gears.timer {
|
||||
timeout = v.update_interval,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
v:_get_status()
|
||||
end
|
||||
}
|
||||
|
||||
return v
|
||||
end
|
||||
|
||||
return P
|
|
@ -0,0 +1,84 @@
|
|||
local P = {}
|
||||
|
||||
function P.new()
|
||||
widget = {}
|
||||
|
||||
widget.icon = wibox.widget {
|
||||
resize = true,
|
||||
image = beautiful.icons.volume.mute,
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
widget.arc = wibox.widget {
|
||||
{
|
||||
widget.icon,
|
||||
top = beautiful.dpi(1),
|
||||
bottom = beautiful.dpi(1),
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
max_value = 1,
|
||||
thickness = beautiful.dpi(4),
|
||||
start_angle = 4.71238898, -- 2pi*3/4
|
||||
--forced_height = beautiful.dpi(16),
|
||||
--forced_width = beautiful.dpi(16),
|
||||
colors = {"#27D4CC", "#00446B"},
|
||||
bg = "#FFFFFF30",
|
||||
paddings = beautiful.dpi(2),
|
||||
widget = wibox.container.arcchart
|
||||
}
|
||||
|
||||
--[[
|
||||
widget.bar = wibox.widget {
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
--forced_height = 20,
|
||||
forced_width = beautiful.dpi(50),
|
||||
paddings = 0,
|
||||
border_width = 0,
|
||||
color = {
|
||||
type = "linear",
|
||||
from = {0, 0}, to = {beautiful.dpi(50), 0},
|
||||
stops = { { 0, "#27D4CC" }, { 1, "#00446B" }}
|
||||
},
|
||||
background_color = "#FFFFFF30",
|
||||
widget = wibox.widget.progressbar,
|
||||
shape = gears.shape.rounded_bar,
|
||||
}
|
||||
}
|
||||
--]]
|
||||
|
||||
widget.widget = wibox.widget {
|
||||
{
|
||||
{ -- Right space
|
||||
widget = wibox.widget.separator,
|
||||
color = beautiful.color.transparent,
|
||||
forced_width = beautiful.dpi(3)
|
||||
},
|
||||
{
|
||||
widget.arc,
|
||||
top = beautiful.dpi(2),
|
||||
bottom = beautiful.dpi(2),
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
{ -- Left space
|
||||
widget = wibox.widget.separator,
|
||||
color = beautiful.color.transparent,
|
||||
forced_width = beautiful.dpi(3)
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
layout = wibox.container.background,
|
||||
}
|
||||
|
||||
widget.widget:connect_signal("mouse::enter", function(result)
|
||||
widget.widget.bg = beautiful.color.bar.hover_bg
|
||||
end)
|
||||
|
||||
widget.widget:connect_signal("mouse::leave", function(result)
|
||||
widget.widget.bg = beautiful.color.transparent
|
||||
end)
|
||||
|
||||
return widget
|
||||
end
|
||||
|
||||
return P
|
|
@ -1,7 +1,6 @@
|
|||
return {
|
||||
backlight = require("wrapper.backlight"),
|
||||
volume = require("wrapper.volume"),
|
||||
sound = require("wrapper.sound"),
|
||||
ibus = require("wrapper.ibus"),
|
||||
mdadm = require("wrapper.mdadm")
|
||||
--mdadm = require("wrapper.mdadm")
|
||||
}
|
||||
|
|
|
@ -1,146 +0,0 @@
|
|||
local volume = {}
|
||||
volume.commands = {}
|
||||
|
||||
|
||||
-- Create pamixer option string
|
||||
volume.pamixer_options = ""
|
||||
if (conf.pamixer_sink ~= "") then
|
||||
volume.pamixer_options = volume.pamixer_options .. " --sink " .. conf.pamixer_sink
|
||||
end
|
||||
|
||||
function volume.commands:up()
|
||||
awful.spawn("pamixer --increase 5" .. volume.pamixer_options, false)
|
||||
end
|
||||
|
||||
function volume.commands:down()
|
||||
awful.spawn("pamixer --decrease 5" .. volume.pamixer_options, false)
|
||||
end
|
||||
|
||||
function volume.commands:set(value)
|
||||
awful.spawn("pamixer --set_volume" .. tostring(value) .. " " .. volume.pamixer_options, false)
|
||||
end
|
||||
|
||||
function volume.commands:mute()
|
||||
awful.spawn("pamixer --mute" .. volume.pamixer_options, false)
|
||||
end
|
||||
|
||||
function volume.commands:unmute()
|
||||
awful.spawn("pamixer --unmute" .. volume.pamixer_options, false)
|
||||
end
|
||||
|
||||
function volume.commands:get(callback)
|
||||
local muted
|
||||
local value
|
||||
|
||||
awful.spawn.easy_async("pamixer --get-mute --get-volume" .. volume.pamixer_options,
|
||||
function(stdout, stderr, exitreason, exitcode)
|
||||
muted = string.match(stdout, "(%w%w%w%w%w?) ") -- "true" or "false"
|
||||
muted = (muted == "true")
|
||||
|
||||
value = string.match(stdout, "(%d?%d?%d)") -- (\d?\d?\d)\%)
|
||||
|
||||
if (value == nil) then
|
||||
value = false
|
||||
else
|
||||
value = tonumber(string.format("% 3d", value))
|
||||
end
|
||||
|
||||
callback({
|
||||
mute = muted,
|
||||
value = value
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
function volume.commands:watch(timeout, callback, widget)
|
||||
awful.widget.watch(
|
||||
"pamixer --get-mute --get-volume " .. volume.pamixer_options,
|
||||
timeout, scallback, widget
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
volume.hooks = {}
|
||||
volume.add_hook = function(callback)
|
||||
volume.hooks[#volume.hooks + 1] = callback
|
||||
end
|
||||
|
||||
volume.exec_hooks = function()
|
||||
volume.commands:get(function(status)
|
||||
for i=1, #volume.hooks do
|
||||
volume.hooks[i](status)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
volume.up = function()
|
||||
if volume.muted then
|
||||
volume.unmute()
|
||||
end
|
||||
|
||||
volume.commands:up()
|
||||
wrapper.sound.play("volume_up")
|
||||
|
||||
volume.exec_hooks()
|
||||
end
|
||||
|
||||
volume.down = function()
|
||||
if volume.muted then
|
||||
volume.unmute()
|
||||
end
|
||||
|
||||
volume.commands:down()
|
||||
wrapper.sound.play("volume_down")
|
||||
|
||||
volume.exec_hooks()
|
||||
end
|
||||
|
||||
volume.mute = function()
|
||||
volume.commands:mute()
|
||||
volume.muted = true
|
||||
|
||||
-- Spawn notification
|
||||
local n = naughty.notify({
|
||||
title = "Volume muted",
|
||||
text = "Silence!",
|
||||
timeout = 1,
|
||||
replaces_id = volume.notificationid
|
||||
})
|
||||
|
||||
volume.notificationid = n.id
|
||||
|
||||
volume.exec_hooks()
|
||||
end
|
||||
|
||||
volume.unmute = function()
|
||||
volume.commands:unmute()
|
||||
volume.muted = false
|
||||
|
||||
-- Spawn notification
|
||||
local n = naughty.notify({
|
||||
title = "Volume unmuted",
|
||||
text = "Loud.",
|
||||
timeout = 1,
|
||||
replaces_id = volume.notificationid
|
||||
})
|
||||
|
||||
volume.notificationid = n.id
|
||||
|
||||
volume.exec_hooks()
|
||||
end
|
||||
|
||||
volume.togglemute = function()
|
||||
volume.commands:get(function(status)
|
||||
if status.mute then
|
||||
volume.unmute()
|
||||
else
|
||||
volume.mute()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Make sure volume is unmuted at startup
|
||||
volume.commands:unmute()
|
||||
|
||||
return volume
|
Loading…
Reference in New Issue