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

renaming rockspec file and adding optional dependencies as regular dependencies
[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
17 local math         = { modf   = math.modf }
18 local mouse        = mouse
19 local string       = { format = string.format,
20                        match  = string.match,
21                        rep    = string.rep }
22 local tonumber     = tonumber
23
24 local setmetatable = setmetatable
25
26 -- ALSA volume bar
27 -- lain.widgets.pulsebar
28 local pulsebar = {
29     sink = 0,
30
31     colors = {
32         background = beautiful.bg_normal,
33         mute       = "#EB8F8F",
34         unmute     = "#A4CE8A"
35     },
36
37     mixer = "pavucontrol",
38
39     notifications = {
40         font      = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")),
41         font_size = "11",
42         color     = beautiful.fg_normal,
43         bar_size  = 18,
44         screen    = 1
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         screen  = pulsebar.notifications.screen,
59         font    = pulsebar.notifications.font .. " " ..
60                   pulsebar.notifications.font_size,
61         fg      = pulsebar.notifications.color
62     }
63
64     if pulsebar._muted
65     then
66         preset.title = "Sink " .. pulsebar.sink .. " - Muted"
67     else
68         preset.title = "Sink " .. pulsebar.sink .. " - " .. pulsebar._current_level .. "%"
69     end
70
71     int = math.modf((pulsebar._current_level / 100) * pulsebar.notifications.bar_size)
72     preset.text = "["
73                 .. string.rep("|", int)
74                 .. string.rep(" ", pulsebar.notifications.bar_size - int)
75                 .. "]"
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.followmouse   = args.followmouse or false
109
110     pulsebar.bar = awful.widget.progressbar()
111
112     pulsebar.bar:set_background_color(pulsebar.colors.background)
113     pulsebar.bar:set_color(pulsebar.colors.unmute)
114     pulsebar.tooltip = awful.tooltip({ objects = { pulsebar.bar } })
115     pulsebar.bar:set_width(width)
116     pulsebar.bar:set_height(height)
117     pulsebar.bar:set_ticks(ticks)
118     pulsebar.bar:set_ticks_size(ticks_size)
119     pulsebar.bar:set_vertical(vertical)
120
121     function pulsebar.update()
122         if scallback then pulseaudio.cmd = scallback() end
123         local s = read_pipe(pulsebar.cmd)
124
125         volume_now = {}
126         volume_now.left  = tonumber(string.match(s, ":.-(%d+)%%"))
127         volume_now.right = tonumber(string.match(s, ":.-(%d+)%%"))
128         volume_now.muted = string.match(s, "muted: (%S+)")
129
130         local volu = volume_now.left
131         local mute = volume_now.muted
132
133         if (volu and volu ~= pulsebar._current_level) or (mute and mute ~= pulsebar._muted)
134         then
135             pulsebar._current_level = volu
136             pulsebar.bar:set_value(pulsebar._current_level / 100)
137             if not mute and volu == 0 or mute == "yes"
138             then
139                 pulsebar._muted = true
140                 pulsebar.tooltip:set_text (" [Muted] ")
141                 pulsebar.bar:set_color(pulsebar.colors.mute)
142             else
143                 pulsebar._muted = false
144                 pulsebar.tooltip:set_text(string.format(" %s:%s ", pulsebar.sink, volu))
145                 pulsebar.bar:set_color(pulsebar.colors.unmute)
146             end
147             settings()
148         end
149     end
150
151     pulsebar.bar:buttons (awful.util.table.join (
152           awful.button ({}, 1, function()
153             awful.util.spawn(pulsebar.mixer)
154           end)
155     ))
156
157     timer_id = string.format("pulsebar-%s", pulsebar.sink)
158
159     newtimer(timer_id, timeout, pulsebar.update)
160
161     return pulsebar
162 end
163
164 return setmetatable(pulsebar, { __call = function(_, ...) return worker(...) end })