]> git.madduck.net Git - etc/awesome.git/blob - widgets/pulsebar.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

net/mpd widget resize fix; #248
[etc/awesome.git] / widgets / pulsebar.lua
1
2 --[[
3                                                   
4      Licensed under GNU General Public License v2 
5       * (c) 2013, Luke Bonham                     
6       * (c) 2013, Rman                            
7                                                   
8 --]]
9
10 local newtimer     = require("lain.helpers").newtimer
11 local read_pipe    = require("lain.helpers").read_pipe
12
13 local awful        = require("awful")
14 local beautiful    = require("beautiful")
15 local naughty      = require("naughty")
16 local wibox        = require("wibox")
17
18 local math         = { modf   = math.modf }
19 local mouse        = mouse
20 local string       = { format = string.format,
21                        match  = string.match,
22                        rep    = string.rep }
23 local tonumber     = tonumber
24
25 local setmetatable = setmetatable
26
27 -- ALSA volume bar
28 -- lain.widgets.pulsebar
29 local pulsebar = {
30     sink = 0,
31     step = "1%",
32
33     colors = {
34         background = beautiful.bg_normal,
35         mute       = "#EB8F8F",
36         unmute     = "#A4CE8A"
37     },
38
39     mixer = "pavucontrol",
40
41     notifications = {
42         font      = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")),
43         font_size = "11",
44         color     = beautiful.fg_normal,
45         bar_size  = 18,
46         screen    = 1
47     },
48
49     _current_level = 0,
50     _muted         = false
51 }
52
53 function pulsebar.notify()
54     pulsebar.update()
55
56     local preset = {
57         title   = "",
58         text    = "",
59         timeout = 5,
60         screen  = pulsebar.notifications.screen,
61         font    = pulsebar.notifications.font .. " " ..
62                   pulsebar.notifications.font_size,
63         fg      = pulsebar.notifications.color
64     }
65
66     if pulsebar._muted
67     then
68         preset.title = "Sink " .. pulsebar.sink .. " - Muted"
69     else
70         preset.title = "Sink " .. pulsebar.sink .. " - " .. pulsebar._current_level .. "%"
71     end
72
73     int = math.modf((pulsebar._current_level / 100) * pulsebar.notifications.bar_size)
74     preset.text = "["
75                 .. string.rep("|", int)
76                 .. string.rep(" ", pulsebar.notifications.bar_size - int)
77                 .. "]"
78
79     if pulsebar.followmouse then
80         preset.screen = mouse.screen
81     end
82
83     if pulsebar._notify ~= nil then
84         pulsebar._notify = naughty.notify ({
85             replaces_id = pulsebar._notify.id,
86             preset      = preset,
87         })
88     else
89         pulsebar._notify = naughty.notify ({
90             preset = preset,
91         })
92     end
93 end
94
95 local function worker(args)
96     local args       = args or {}
97     local timeout    = args.timeout or 5
98     local settings   = args.settings or function() end
99     local width      = args.width or 63
100     local height     = args.heigth or 1
101     local ticks      = args.ticks or false
102     local ticks_size = args.ticks_size or 7
103     local vertical   = args.vertical or false
104     local scallback  = args.scallback
105
106     pulsebar.cmd           = args.cmd or string.format("pacmd list-sinks | sed -n -e '0,/*/d' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p'")
107     pulsebar.colors        = args.colors or pulsebar.colors
108     pulsebar.notifications = args.notifications or pulsebar.notifications
109     pulsebar.sink          = args.sink or 0
110     pulsebar.step          = args.step or pulsebar.step
111     pulsebar.followmouse   = args.followmouse or false
112
113     pulsebar.bar = wibox.widget.progressbar()
114
115     pulsebar.bar:set_background_color(pulsebar.colors.background)
116     pulsebar.bar:set_color(pulsebar.colors.unmute)
117     pulsebar.tooltip = awful.tooltip({ objects = { pulsebar.bar } })
118     pulsebar.bar:set_width(width)
119     pulsebar.bar:set_height(height)
120     pulsebar.bar:set_ticks(ticks)
121     pulsebar.bar:set_ticks_size(ticks_size)
122     pulsebar.bar:set_vertical(vertical)
123
124     function pulsebar.update()
125         if scallback then pulseaudio.cmd = scallback() end
126         local s = read_pipe(pulsebar.cmd)
127
128         volume_now = {}
129         volume_now.left  = tonumber(string.match(s, ":.-(%d+)%%"))
130         volume_now.right = tonumber(string.match(s, ":.-(%d+)%%"))
131         volume_now.muted = string.match(s, "muted: (%S+)")
132
133         local volu = volume_now.left
134         local mute = volume_now.muted
135
136         if (volu and volu ~= pulsebar._current_level) or (mute and mute ~= pulsebar._muted)
137         then
138             pulsebar._current_level = volu
139             pulsebar.bar:set_value(pulsebar._current_level / 100)
140             if not mute and volu == 0 or mute == "yes"
141             then
142                 pulsebar._muted = true
143                 pulsebar.tooltip:set_text (" [Muted] ")
144                 pulsebar.bar:set_color(pulsebar.colors.mute)
145             else
146                 pulsebar._muted = false
147                 pulsebar.tooltip:set_text(string.format(" %s:%s ", pulsebar.sink, volu))
148                 pulsebar.bar:set_color(pulsebar.colors.unmute)
149             end
150             settings()
151         end
152     end
153
154     pulsebar.bar:buttons(awful.util.table.join (
155           awful.button({}, 1, function()
156             awful.util.spawn(pulsebar.mixer)
157           end),
158           awful.button({}, 2, function()
159                                                 awful.util.spawn(string.format("pactl set-sink-volume %d 100%%", pulsebar.sink))
160             pulsebar.update()
161           end),
162           awful.button({}, 3, function()
163                                                 awful.util.spawn(string.format("pactl set-sink-mute %d toggle", pulsebar.sink))
164             pulsebar.update()
165           end),
166           awful.button({}, 4, function()
167                                                 awful.util.spawn(string.format("pactl set-sink-volume %d +%s", pulsebar.sink, pulsebar.step))
168             pulsebar.update()
169           end),
170           awful.button({}, 5, function()
171                                                 awful.util.spawn(string.format("pactl set-sink-volume %d -%s", pulsebar.sink, pulsebar.step))
172             pulsebar.update()
173                                         end)
174     ))
175
176     timer_id = string.format("pulsebar-%s", pulsebar.sink)
177
178     newtimer(timer_id, timeout, pulsebar.update)
179
180     return pulsebar
181 end
182
183 return setmetatable(pulsebar, { __call = function(_, ...) return worker(...) end })