]> 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:

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