]> git.madduck.net Git - etc/awesome.git/blob - widget/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:

Workaround premature end of file with awful.spawn.easy_async
[etc/awesome.git] / widget / 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 helpers      = require("lain.helpers")
11 local awful        = require("awful")
12 local naughty      = require("naughty")
13 local wibox        = require("wibox")
14 local math         = { modf   = math.modf }
15 local string       = { format = string.format,
16                        gmatch = string.gmatch,
17                        match  = string.match,
18                        rep    = string.rep }
19 local type         = type
20 local tonumber     = tonumber
21 local setmetatable = setmetatable
22
23 -- Pulseaudio volume bar
24 -- lain.widget.pulsebar
25 local pulsebar = {
26     colors = {
27         background = "#000000",
28         mute       = "#EB8F8F",
29         unmute     = "#A4CE8A"
30     },
31
32     _current_level = 0,
33     _muted         = false
34 }
35
36 local function factory(args)
37     local args       = args or {}
38     local timeout    = args.timeout or 5
39     local settings   = args.settings or function() end
40     local width      = args.width or 63
41     local height     = args.heigth or 1
42     local ticks      = args.ticks or false
43     local ticks_size = args.ticks_size or 7
44     local scallback  = args.scallback
45
46     pulsebar.cmd           = args.cmd or "pacmd list-sinks | sed -n -e '0,/*/d' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p' -e '/device\\.string/p'"
47     pulsebar.sink          = args.sink or 0
48     pulsebar.colors        = args.colors or pulsebar.colors
49     pulsebar.followtag     = args.followtag or false
50     pulsebar.notifications = args.notification_preset
51
52     if not pulsebar.notification_preset then
53         pulsebar.notification_preset      = {}
54         pulsebar.notification_preset.font = "Monospace 10"
55     end
56
57     pulsebar.bar = wibox.widget {
58         forced_height    = height,
59         forced_width     = width,
60         color            = pulsebar.colors.unmute,
61         background_color = pulsebar.colors.background,
62         margins          = 1,
63         paddings         = 1,
64         ticks            = ticks,
65         ticks_size       = ticks_size,
66         widget           = wibox.widget.progressbar,
67     }
68
69     pulsebar.tooltip = awful.tooltip({ objects = { pulsebar.bar } })
70
71     function pulsebar.update(callback)
72         if scallback then pulseaudio.cmd = scallback() end
73
74         helpers.async({ awful.util.shell, "-c", pulsebar.cmd }, function(s)
75             volume_now = {
76                 index = string.match(s, "index: (%S+)") or "N/A",
77                 sink  = string.match(s, "device.string = \"(%S+)\"") or "N/A",
78                 muted = string.match(s, "muted: (%S+)") or "N/A"
79             }
80
81             local ch = 1
82             volume_now.channel = {}
83             for v in string.gmatch(s, ":.-(%d+)%%") do
84               volume_now.channel[ch] = v
85               ch = ch + 1
86             end
87
88             volume_now.left  = volume_now.channel[1] or "N/A"
89             volume_now.right = volume_now.channel[2] or "N/A"
90
91             local volu = volume_now.left
92             local mute = volume_now.muted
93
94             if (volu and volu ~= pulsebar._current_level) or (mute and mute ~= pulsebar._muted) then
95                 pulsebar._current_level = volu
96                 pulsebar.bar:set_value(pulsebar._current_level / 100)
97                 if (not mute and volu == 0) or mute == "yes" then
98                     pulsebar._muted = true
99                     pulsebar.tooltip:set_text ("[Muted]")
100                     pulsebar.bar.color = pulsebar.colors.mute
101                 else
102                     pulsebar._muted = false
103                     pulsebar.tooltip:set_text(string.format("%s: %s", pulsebar.sink, volu))
104                     pulsebar.bar.color = pulsebar.colors.unmute
105                 end
106
107                 settings()
108
109                 if type(callback) == "function" then callback() end
110             end
111         end)
112     end
113
114     function pulsebar.notify()
115         pulsebar.update(function()
116             local preset = pulsebar.notification_preset
117
118             if pulsebar._muted then
119                 preset.title = string.format("Sink %s - Muted", pulsebar.sink)
120             else
121                 preset.title = string.format("%s - %s%%", pulsebar.sink, pulsebar._current_level)
122             end
123
124             int = math.modf((pulsebar._current_level / 100) * awful.screen.focused().mywibox.height)
125             preset.text = string.format("[%s%s]", string.rep("|", int),
126                           string.rep(" ", awful.screen.focused().mywibox.height - int))
127
128             if pulsebar.followtag then preset.screen = awful.screen.focused() end
129
130             if not pulsebar.notification then
131                 pulsebar.notification = naughty.notify {
132                     preset  = preset,
133                     destroy = function() pulsebar.notification = nil end
134                 }
135             else
136                 naughty.replace_text(pulsebar.notification, preset.title, preset.text)
137             end
138         end)
139     end
140
141     helpers.newtimer(string.format("pulsebar-%s", pulsebar.sink), timeout, pulsebar.update)
142
143     return pulsebar
144 end
145
146 return setmetatable(pulsebar, { __call = function(_, ...) return factory(...) end })