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

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