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

{alsa,pulse}bar updated to awesome 4.0
[etc/awesome.git] / widgets / alsabar.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.alsabar
29 local alsabar = {
30     channel = "Master",
31     step    = "1%",
32
33     colors = {
34         background = beautiful.bg_normal,
35         mute       = "#EB8F8F",
36         unmute     = "#A4CE8A"
37     },
38
39     terminal = terminal or "xterm",
40     mixer    = string.format("%s -e alsamixer", terminal),
41
42     notifications = {
43         font      = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")),
44         font_size = "11",
45         color     = beautiful.fg_normal,
46         bar_size  = 18,
47         screen    = 1
48     },
49
50     _current_level = 0,
51     _muted         = false
52 }
53
54 function alsabar.notify()
55     alsabar.update()
56
57     local preset = {
58         title   = "",
59         text    = "",
60         timeout = 5,
61         screen  = alsabar.notifications.screen,
62         font    = string.format("%s %s", alsabar.notifications.font,
63                   alsabar.notifications.font_size),
64         fg      = alsabar.notifications.color
65     }
66
67     if alsabar._muted
68     then
69         preset.title = string.format("%s - Muted", alsabar.channel)
70     else
71         preset.title = string.format("%s - %s%%", alsabar.channel, alsabar._current_level)
72     end
73
74     int = math.modf((alsabar._current_level / 100) * alsabar.notifications.bar_size)
75     preset.text = string.format("[%s%s]", string.rep("|", int),
76                   string.rep(" ", alsabar.notifications.bar_size - int))
77
78     if alsabar.followmouse then
79         preset.screen = mouse.screen
80     end
81
82     if alsabar._notify ~= nil then
83         alsabar._notify = naughty.notify ({
84             replaces_id = alsabar._notify.id,
85             preset      = preset,
86         })
87     else
88         alsabar._notify = naughty.notify ({
89             preset = preset,
90         })
91     end
92 end
93
94 local function worker(args)
95     local args         = args or {}
96     local timeout      = args.timeout or 5
97     local settings     = args.settings or function() end
98     local width        = args.width or 63
99     local height       = args.heigth or 1
100     local ticks        = args.ticks or false
101     local ticks_size   = args.ticks_size or 7
102     local vertical     = args.vertical or false
103
104     alsabar.cmd           = args.cmd or "amixer"
105     alsabar.channel       = args.channel or alsabar.channel
106     alsabar.togglechannel = args.togglechannel
107     alsabar.step          = args.step or alsabar.step
108     alsabar.colors        = args.colors or alsabar.colors
109     alsabar.notifications = args.notifications or alsabar.notifications
110     alsabar.followmouse   = args.followmouse or false
111
112     alsabar.bar = wibox.widget {
113         forced_height    = height,
114         forced_width     = width,
115         color            = alsabar.colors.unmute,
116         background_color = alsabar.colors.background,
117         margins          = 1,
118         paddings         = 1,
119         ticks            = ticks,
120         ticks_size       = ticks_size,
121         widget           = wibox.widget.progressbar,
122         layout           = vertical and wibox.container.rotate
123     }
124
125     alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
126
127     function alsabar.update()
128         -- Get mixer control contents
129         local mixer = read_pipe(string.format("%s get %s", alsabar.cmd, alsabar.channel))
130
131         -- Capture mixer control state:          [5%] ... ... [on]
132         local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
133
134         -- HDMIs can have a channel different from Master for toggling mute
135         if alsabar.togglechannel then
136             mute = string.match(read_pipe(string.format("%s get %s", alsabar.cmd, alsabar.togglechannel)), "%[(%a+)%]")
137         end
138
139         if (volu and tonumber(volu) ~= alsabar._current_level) or (mute and string.match(mute, "on") ~= alsabar._muted)
140         then
141             alsabar._current_level = tonumber(volu) or alsabar._current_level
142             alsabar.bar:set_value(alsabar._current_level / 100)
143             if (not mute and tonumber(volu) == 0) or mute == "off"
144             then
145                 alsabar._muted = true
146                 alsabar.tooltip:set_text ("[Muted]")
147                 alsabar.bar.color = alsabar.colors.mute
148             else
149                 alsabar._muted = false
150                 alsabar.tooltip:set_text(string.format("%s: %s", alsabar.channel, volu))
151                 alsabar.bar.color = alsabar.colors.unmute
152             end
153
154             volume_now = {}
155             volume_now.level = tonumber(volu)
156             volume_now.status = mute
157
158             settings()
159         end
160     end
161
162     alsabar.bar:buttons(awful.util.table.join (
163           awful.button({}, 1, function()
164             awful.util.spawn(alsabar.mixer)
165           end),
166           awful.button({}, 2, function()
167                                                 awful.util.spawn(string.format("%s set %s 100%%", alsabar.cmd, alsabar.channel))
168             pulsebar.update()
169           end),
170           awful.button({}, 3, function()
171             awful.util.spawn(string.format("%s set %s toggle", alsabar.cmd, alsabar.togglechannel or alsabar.channel))
172             alsabar.update()
173           end),
174           awful.button({}, 4, function()
175             awful.util.spawn(string.format("%s set %s %s+", alsabar.cmd, alsabar.channel, alsabar.step))
176             alsabar.update()
177           end),
178           awful.button({}, 5, function()
179             awful.util.spawn(string.format("%s set %s %s-", alsabar.cmd, alsabar.channel, alsabar.step))
180             alsabar.update()
181           end)
182     ))
183
184     timer_id = string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel)
185
186     newtimer(timer_id, timeout, alsabar.update)
187
188     return alsabar
189 end
190
191 return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end })