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

c0787c9dc9f8f458bee059290f5adbbc1739c695
[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    = string.format("%s %s", alsabar.notifications.font,
62                   alsabar.notifications.font_size),
63         fg      = pulsebar.notifications.color
64     }
65
66     if pulsebar._muted
67     then
68         preset.title = string.format("Sink %s - Muted", pulsebar.sink)
69     else
70         preset.title = string.format("%s - %s%%", pulsebar.sink, pulsebar._current_level)
71     end
72
73     int = math.modf((pulsebar._current_level / 100) * pulsebar.notifications.bar_size)
74     preset.text = string.format("[%s%s]", string.rep("|", int),
75                   string.rep(" ", pulsebar.notifications.bar_size - int))
76
77     if pulsebar.followmouse then
78         preset.screen = mouse.screen
79     end
80
81     if pulsebar._notify ~= nil then
82         pulsebar._notify = naughty.notify ({
83             replaces_id = pulsebar._notify.id,
84             preset      = preset,
85         })
86     else
87         pulsebar._notify = naughty.notify ({
88             preset = preset,
89         })
90     end
91 end
92
93 local function worker(args)
94     local args       = args or {}
95     local timeout    = args.timeout or 5
96     local settings   = args.settings or function() end
97     local width      = args.width or 63
98     local height     = args.heigth or 1
99     local ticks      = args.ticks or false
100     local ticks_size = args.ticks_size or 7
101     local vertical   = args.vertical or false
102     local scallback  = args.scallback
103
104     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'")
105     pulsebar.colors        = args.colors or pulsebar.colors
106     pulsebar.notifications = args.notifications or pulsebar.notifications
107     pulsebar.sink          = args.sink or 0
108     pulsebar.step          = args.step or pulsebar.step
109     pulsebar.followmouse   = args.followmouse or false
110
111     pulsebar.bar = wibox.widget {
112         forced_height    = height,
113         forced_width     = width,
114         color            = pulsebar.colors.unmute,
115         background_color = pulsebar.colors.background,
116         margins          = 1,
117         paddings         = 1,
118         ticks            = ticks,
119         ticks_size       = ticks_size,
120         widget           = wibox.widget.progressbar,
121         layout           = vertical and wibox.container.rotate
122     }
123
124     pulsebar.tooltip = awful.tooltip({ objects = { pulsebar.bar } })
125
126     function pulsebar.update()
127         if scallback then pulseaudio.cmd = scallback() end
128         local s = read_pipe(pulsebar.cmd)
129
130         volume_now = {}
131         volume_now.left  = tonumber(string.match(s, ":.-(%d+)%%"))
132         volume_now.right = tonumber(string.match(s, ":.-(%d+)%%"))
133         volume_now.muted = string.match(s, "muted: (%S+)")
134
135         local volu = volume_now.left
136         local mute = volume_now.muted
137
138         if (volu and volu ~= pulsebar._current_level) or (mute and mute ~= pulsebar._muted)
139         then
140             pulsebar._current_level = volu
141             pulsebar.bar:set_value(pulsebar._current_level / 100)
142             if (not mute and volu == 0) or mute == "yes"
143             then
144                 pulsebar._muted = true
145                 pulsebar.tooltip:set_text ("[Muted]")
146                 pulsebar.bar.color(pulsebar.colors.mute)
147             else
148                 pulsebar._muted = false
149                 pulsebar.tooltip:set_text(string.format("%s: %s", pulsebar.sink, volu))
150                 pulsebar.bar.color(pulsebar.colors.unmute)
151             end
152             settings()
153         end
154     end
155
156     pulsebar.bar:buttons(awful.util.table.join (
157           awful.button({}, 1, function()
158             awful.util.spawn(pulsebar.mixer)
159           end),
160           awful.button({}, 2, function()
161                                                 awful.util.spawn(string.format("pactl set-sink-volume %d 100%%", pulsebar.sink))
162             pulsebar.update()
163           end),
164           awful.button({}, 3, function()
165                                                 awful.util.spawn(string.format("pactl set-sink-mute %d toggle", pulsebar.sink))
166             pulsebar.update()
167           end),
168           awful.button({}, 4, function()
169                                                 awful.util.spawn(string.format("pactl set-sink-volume %d +%s", pulsebar.sink, pulsebar.step))
170             pulsebar.update()
171           end),
172           awful.button({}, 5, function()
173                                                 awful.util.spawn(string.format("pactl set-sink-volume %d -%s", pulsebar.sink, pulsebar.step))
174             pulsebar.update()
175                                         end)
176     ))
177
178     timer_id = string.format("pulsebar-%s", pulsebar.sink)
179
180     newtimer(timer_id, timeout, pulsebar.update)
181
182     return pulsebar
183 end
184
185 return setmetatable(pulsebar, { __call = function(_, ...) return worker(...) end })