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

fixed spelling heigth > height; added support for mouse buttons 1 through 5; added...
[etc/awesome.git] / widgets / alsabar.lua
1 --[[
2      Licensed under GNU General Public License v2
3       * (c) 2013, Luke Bonham
4       * (c) 2013, Rman
5 --]]
6
7 local helpers      = require("lain.helpers")
8 local awful        = require("awful")
9 local beautiful    = require("beautiful")
10 local naughty      = require("naughty")
11 local wibox        = require("wibox")
12 local math         = { modf   = math.modf }
13 local string       = { format = string.format,
14                        match  = string.match,
15                        rep    = string.rep }
16 local tonumber     = tonumber
17 local type         = type
18 local setmetatable = setmetatable
19 local terminal     = "urxvtc" or "xterm"
20
21 -- ALSA volume bar
22 -- lain.widgets.alsabar
23 local alsabar = {
24     channel = "Master",
25     step    = "1%",
26     mixer   = "amixer",
27
28     colors = {
29         background = beautiful.bg_normal,
30         mute       = "#EB8F8F",
31         unmute     = "#A4CE8A"
32     },
33
34     notifications = {
35         font      = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")),
36         font_size = "11",
37         color     = beautiful.fg_normal,
38         screen    = 1
39     },
40
41     _current_level = 0,
42     _muted         = false
43 }
44
45 local function worker(args)
46     local args         = args or {}
47     local timeout      = args.timeout or 5
48     local settings     = args.settings or function() end
49     local width        = args.width or 63
50     local height       = args.height or 1
51     local ticks        = args.ticks or false
52     local ticks_size   = args.ticks_size or 7
53     local vertical     = args.vertical or false
54
55     alsabar.mixer         = args.mixer or alsabar.mixer
56     alsabar.channel       = args.channel or alsabar.channel
57     alsabar.togglechannel = args.togglechannel or alsabar.togglechannel
58     alsabar.cmd           = args.cmd or {"bash", "-c", string.format("%s get %s", alsabar.mixer, alsabar.channel)}
59     alsabar.step          = args.step or alsabar.step
60     alsabar.colors        = args.colors or alsabar.colors
61     alsabar.notifications = args.notifications or alsabar.notifications
62     alsabar.followtag     = args.followtag or false
63     if alsabar.togglechannel then
64             alsabar.cmd   = args.cmd or { "bash", "-c", string.format("%s get %s; %s get %s", alsabar.mixer, alsabar.channel, alsabar.mixer, alsabar.togglechannel)}
65     end
66
67     alsabar.bar = wibox.widget {
68         forced_height    = height,
69         forced_width     = width,
70         color            = alsabar.colors.unmute,
71         background_color = alsabar.colors.background,
72         margins          = 1,
73         paddings         = 1,
74         ticks            = ticks,
75         ticks_size       = ticks_size,
76         widget           = wibox.widget.progressbar,
77         layout           = vertical and wibox.container.rotate
78     }
79
80     alsabar.bar:buttons (awful.util.table.join(
81         awful.button({}, 1, function()
82                 awful.spawn(string.format('%s -e alsamixer', terminal))
83         end),
84         awful.button({}, 2, function()
85                 awful.spawn(string.format("%s set %s 100%%", alsabar.mixer, alsabar.channel))
86                 alsabar.update()
87         end),
88         awful.button({}, 3, function()
89                 awful.spawn(string.format("%s set %s toggle", alsabar.mixer, alsabar.togglechannel or alsabar.channel))
90                 alsabar.update()
91         end),
92         awful.button({}, 4, function()
93                 awful.spawn(string.format("%s set %s %s+", alsabar.mixer, alsabar.channel, alsabar.step))
94                 alsabar.update()
95         end),
96         awful.button({}, 5, function()
97                 awful.spawn(string.format("%s set %s %s-", alsabar.mixer, alsabar.channel, alsabar.step))
98                 alsabar.update()
99         end)))
100
101     alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
102
103     function alsabar.update(callback)
104         helpers.async(alsabar.cmd, function(mixer)
105             local volu,mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
106             if (volu and tonumber(volu) ~= alsabar._current_level) or (mute and string.match(mute, "on") ~= alsabar._muted)
107             then
108                 alsabar._current_level = tonumber(volu) or alsabar._current_level
109                 alsabar.bar:set_value(alsabar._current_level / 100)
110                 if (not mute and tonumber(volu) == 0) or mute == "off"
111                 then
112                     alsabar._muted = true
113                     alsabar.tooltip:set_text ("[Muted]")
114                     alsabar.bar.color = alsabar.colors.mute
115                 else
116                     alsabar._muted = false
117                     alsabar.tooltip:set_text(string.format("%s: %s", alsabar.channel, volu))
118                     alsabar.bar.color = alsabar.colors.unmute
119                 end
120
121                 volume_now = {}
122                 volume_now.level = tonumber(volu)
123                 volume_now.status = mute
124
125                 settings()
126
127                 if type(callback) == "function" then callback() end
128             end
129         end)
130     end
131
132     function alsabar.notify()
133         alsabar.update(function()
134             local preset = {
135                 title   = "",
136                 text    = "",
137                 timeout = 5,
138                 screen  = alsabar.notifications.screen,
139                 font    = string.format("%s %s", alsabar.notifications.font,
140                           alsabar.notifications.font_size),
141                 fg      = alsabar.notifications.color
142             }
143
144             if alsabar._muted then
145                 preset.title = string.format("%s - Muted", alsabar.channel)
146             else
147                 preset.title = string.format("%s - %s%%", alsabar.channel, alsabar._current_level)
148             end
149
150             int = math.modf((alsabar._current_level / 100) * awful.screen.focused().mywibox.height)
151             preset.text = string.format("[%s%s]", string.rep("|", int),
152                           string.rep(" ", awful.screen.focused().mywibox.height - int))
153
154             if alsabar.followtag then preset.screen = awful.screen.focused() end
155
156             if alsabar._notify then
157                 alsabar._notify = naughty.notify ({
158                     replaces_id = alsabar._notify.id,
159                     preset      = preset,
160                 })
161             else
162                 alsabar._notify = naughty.notify ({ preset = preset })
163             end
164         end)
165     end
166
167     timer_id = string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel)
168     helpers.newtimer(timer_id, timeout, alsabar.update)
169
170     return alsabar
171 end
172
173 return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end })