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

#263: followtag default to true; changing quake definition
[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 -- Pulseaudio 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     },
46
47     _current_level = 0,
48     _muted         = false
49 }
50
51 function pulsebar.notify()
52     pulsebar.update()
53
54     local preset = {
55         title   = "",
56         text    = "",
57         timeout = 5,
58         font    = string.format("%s %s", pulsebar.notifications.font,
59                   pulsebar.notifications.font_size),
60         fg      = pulsebar.notifications.color
61     }
62
63     if pulsebar._muted
64     then
65         preset.title = string.format("Sink %s - Muted", pulsebar.sink)
66     else
67         preset.title = string.format("%s - %s%%", pulsebar.sink, pulsebar._current_level)
68     end
69
70     int = math.modf((pulsebar._current_level / 100) * awful.screen.focused().mywibox.height)
71     preset.text = string.format("[%s%s]", string.rep("|", int),
72                   string.rep(" ", awful.screen.focused().mywibox.height - int))
73
74     if pulsebar.followtag then
75         preset.screen = awful.screen.focused()
76     end
77
78     if pulsebar._notify ~= nil then
79         pulsebar._notify = naughty.notify ({
80             replaces_id = pulsebar._notify.id,
81             preset      = preset,
82         })
83     else
84         pulsebar._notify = naughty.notify ({
85             preset = preset,
86         })
87     end
88 end
89
90 local function worker(args)
91     local args       = args or {}
92     local timeout    = args.timeout or 5
93     local settings   = args.settings or function() end
94     local width      = args.width or 63
95     local height     = args.heigth or 1
96     local ticks      = args.ticks or false
97     local ticks_size = args.ticks_size or 7
98     local vertical   = args.vertical or false
99     local scallback  = args.scallback
100
101     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'")
102     pulsebar.colors        = args.colors or pulsebar.colors
103     pulsebar.notifications = args.notifications or pulsebar.notifications
104     pulsebar.sink          = args.sink or 0
105     pulsebar.step          = args.step or pulsebar.step
106     pulsebar.followtag   = args.followtag or false
107
108     pulsebar.bar = wibox.widget {
109         forced_height    = height,
110         forced_width     = width,
111         color            = pulsebar.colors.unmute,
112         background_color = pulsebar.colors.background,
113         margins          = 1,
114         paddings         = 1,
115         ticks            = ticks,
116         ticks_size       = ticks_size,
117         widget           = wibox.widget.progressbar,
118         layout           = vertical and wibox.container.rotate
119     }
120
121     pulsebar.tooltip = awful.tooltip({ objects = { pulsebar.bar } })
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.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.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 })