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

9380a34b8d06e59f1498f7cb36ad7a7c1cda3e8a
[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 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                        match  = string.match,
17                        rep    = string.rep }
18 local type         = type
19 local tonumber     = tonumber
20 local setmetatable = setmetatable
21
22 -- Pulseaudio volume bar
23 -- lain.widgets.pulsebar
24 local pulsebar = {
25     colors = {
26         background = "#000000",
27         mute       = "#EB8F8F",
28         unmute     = "#A4CE8A"
29     },
30
31     _current_level = 0,
32     _muted         = false
33 }
34
35 local function worker(args)
36     local args       = args or {}
37     local timeout    = args.timeout or 5
38     local settings   = args.settings or function() end
39     local width      = args.width or 63
40     local height     = args.heigth or 1
41     local ticks      = args.ticks or false
42     local ticks_size = args.ticks_size or 7
43     local vertical   = args.vertical or false
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      = naughty.config.defaults
54         pulsebar.notification_preset.font = "Monospace 11"
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         layout           = vertical and wibox.container.rotate
68     }
69
70     pulsebar.tooltip = awful.tooltip({ objects = { pulsebar.bar } })
71
72     function pulsebar.update(callback)
73         if scallback then pulseaudio.cmd = scallback() end
74
75         helpers.async({ awful.util.shell, "-c", pulsebar.cmd }, function(s)
76             volume_now = {
77                 index = string.match(s, "index: (%S+)") or "N/A",
78                 sink  = string.match(s, "device.string = \"(%S+)\"") or "N/A",
79                 muted = string.match(s, "muted: (%S+)") or "N/A"
80             }
81
82             local ch = 1
83             volume_now.channel = {}
84             for v in string.gmatch(s, ":.-(%d+)%%") do
85               volume_now.channel[ch] = v
86               ch = ch + 1
87             end
88
89             volume_now.left  = volume_now.channel[1] or "N/A"
90             volume_now.right = volume_now.channel[2] or "N/A"
91
92             local volu = volume_now.left
93             local mute = volume_now.muted
94
95             if (volu and volu ~= pulsebar._current_level) or (mute and mute ~= pulsebar._muted) then
96                 pulsebar._current_level = volu
97                 pulsebar.bar:set_value(pulsebar._current_level / 100)
98                 if (not mute and volu == 0) or mute == "yes" then
99                     pulsebar._muted = true
100                     pulsebar.tooltip:set_text ("[Muted]")
101                     pulsebar.bar.color = pulsebar.colors.mute
102                 else
103                     pulsebar._muted = false
104                     pulsebar.tooltip:set_text(string.format("%s: %s", pulsebar.sink, volu))
105                     pulsebar.bar.color = pulsebar.colors.unmute
106                 end
107
108                 settings()
109
110                 if type(callback) == "function" then callback() end
111             end
112         end)
113     end
114
115     function pulsebar.notify()
116         pulsebar.update(function()
117             local preset = pulsebar.notification_preset
118
119             if pulsebar._muted then
120                 preset.title = string.format("Sink %s - Muted", pulsebar.sink)
121             else
122                 preset.title = string.format("%s - %s%%", pulsebar.sink, pulsebar._current_level)
123             end
124
125             int = math.modf((pulsebar._current_level / 100) * awful.screen.focused().mywibox.height)
126             preset.text = string.format("[%s%s]", string.rep("|", int),
127                           string.rep(" ", awful.screen.focused().mywibox.height - int))
128
129             if pulsebar.followtag then preset.screen = awful.screen.focused() end
130
131             pulsebar.id = naughty.notify ({
132                 replaces_id = pulsebar.id,
133                 preset      = preset
134             }).id
135         end)
136     end
137
138
139     timer_id = string.format("pulsebar-%s", pulsebar.sink)
140
141     helpers.newtimer(timer_id, timeout, pulsebar.update)
142
143     return pulsebar
144 end
145
146 return setmetatable(pulsebar, { __call = function(_, ...) return worker(...) end })