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

net/mpd widget resize fix; #248
[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    = terminal .. " -e alsamixer",
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    = alsabar.notifications.font .. " " ..
63                   alsabar.notifications.font_size,
64         fg      = alsabar.notifications.color
65     }
66
67     if alsabar._muted
68     then
69         preset.title = alsabar.channel .. " - Muted"
70     else
71         preset.title = alsabar.channel .. " - " .. alsabar._current_level .. "%"
72     end
73
74     int = math.modf((alsabar._current_level / 100) * alsabar.notifications.bar_size)
75     preset.text = "["
76                 .. string.rep("|", int)
77                 .. string.rep(" ", alsabar.notifications.bar_size - int)
78                 .. "]"
79
80     if alsabar.followmouse then
81         preset.screen = mouse.screen
82     end
83
84     if alsabar._notify ~= nil then
85         alsabar._notify = naughty.notify ({
86             replaces_id = alsabar._notify.id,
87             preset      = preset,
88         })
89     else
90         alsabar._notify = naughty.notify ({
91             preset = preset,
92         })
93     end
94 end
95
96 local function worker(args)
97     local args       = args or {}
98     local timeout    = args.timeout or 5
99     local settings   = args.settings or function() end
100     local width      = args.width or 63
101     local height     = args.heigth or 1
102     local ticks      = args.ticks or false
103     local ticks_size = args.ticks_size or 7
104     local vertical   = args.vertical or false
105
106     alsabar.cmd           = args.cmd or "amixer"
107     alsabar.channel       = args.channel or alsabar.channel
108     alsabar.togglechannel = args.togglechannel
109     alsabar.step          = args.step or alsabar.step
110     alsabar.colors        = args.colors or alsabar.colors
111     alsabar.notifications = args.notifications or alsabar.notifications
112     alsabar.followmouse   = args.followmouse or false
113
114     alsabar.bar = wibox.widget.progressbar()
115
116     alsabar.bar:set_background_color(alsabar.colors.background)
117     alsabar.bar:set_color(alsabar.colors.unmute)
118     alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
119     alsabar.bar:set_width(width)
120     alsabar.bar:set_height(height)
121     alsabar.bar:set_ticks(ticks)
122     alsabar.bar:set_ticks_size(ticks_size)
123     alsabar.bar:set_vertical(vertical)
124
125     function alsabar.update()
126         -- Get mixer control contents
127         local mixer = read_pipe(string.format("%s get %s", alsabar.cmd, alsabar.channel))
128
129         -- Capture mixer control state:          [5%] ... ... [on]
130         local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
131
132         -- HDMIs can have a channel different from Master for toggling mute
133         if alsabar.togglechannel then
134             mute = string.match(read_pipe(string.format("%s get %s", alsabar.cmd, alsabar.togglechannel)), "%[(%a+)%]")
135         end
136
137         if (volu and tonumber(volu) ~= alsabar._current_level) or (mute and string.match(mute, "on") ~= alsabar._muted)
138         then
139             alsabar._current_level = tonumber(volu) or alsabar._current_level
140             alsabar.bar:set_value(alsabar._current_level / 100)
141             if not mute and tonumber(volu) == 0 or mute == "off"
142             then
143                 alsabar._muted = true
144                 alsabar.tooltip:set_text (" [Muted] ")
145                 alsabar.bar:set_color(alsabar.colors.mute)
146             else
147                 alsabar._muted = false
148                 alsabar.tooltip:set_text(string.format(" %s:%s ", alsabar.channel, volu))
149                 alsabar.bar:set_color(alsabar.colors.unmute)
150             end
151
152             volume_now = {}
153             volume_now.level = tonumber(volu)
154             volume_now.status = mute
155             settings()
156         end
157     end
158
159     alsabar.bar:buttons(awful.util.table.join (
160           awful.button({}, 1, function()
161             awful.util.spawn(alsabar.mixer)
162           end),
163           awful.button({}, 2, function()
164                                                 awful.util.spawn(string.format("%s set %s 100%%", alsabar.cmd, alsabar.channel))
165             pulsebar.update()
166           end),
167           awful.button({}, 3, function()
168             awful.util.spawn(string.format("%s set %s toggle", alsabar.cmd, alsabar.channel))
169             alsabar.update()
170           end),
171           awful.button({}, 4, function()
172             awful.util.spawn(string.format("%s set %s %s+", alsabar.cmd, alsabar.channel, alsabar.step))
173             alsabar.update()
174           end),
175           awful.button({}, 5, function()
176             awful.util.spawn(string.format("%s set %s %s-", alsabar.cmd, alsabar.channel, alsabar.step))
177             alsabar.update()
178           end)
179     ))
180
181     timer_id = string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel)
182
183     newtimer(timer_id, timeout, alsabar.update)
184
185     return alsabar
186 end
187
188 return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end })