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

merge and resolve conflicts from #134; #114
[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
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.alsabar
28 local alsabar = {
29     channel = "Master",
30     step    = "2%",
31
32     colors = {
33         background = beautiful.bg_normal,
34         mute       = "#EB8F8F",
35         unmute     = "#A4CE8A"
36     },
37
38     terminal = terminal or "xterm",
39     mixer    = terminal .. " -e alsamixer",
40
41     notifications = {
42         font      = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")),
43         font_size = "11",
44         color     = beautiful.fg_normal,
45         bar_size  = 18,
46         screen    = 1
47     },
48
49     _current_level = 0,
50     _muted         = false,
51     _status        = "off"
52 }
53
54 function alsabar.notify()
55     alsabar.update()
56
57     local preset = {
58         title   = "",
59         text    = "",
60         timeout = 1,
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 1
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.step          = args.step or alsabar.step
109     alsabar.colors        = args.colors or alsabar.colors
110     alsabar.notifications = args.notifications or alsabar.notifications
111     alsabar.followmouse   = args.followmouse or false
112
113     alsabar.bar = awful.widget.progressbar()
114
115     alsabar.bar:set_background_color(alsabar.colors.background)
116     alsabar.bar:set_color(alsabar.colors.unmute)
117     alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
118     alsabar.bar:set_width(width)
119     alsabar.bar:set_height(height)
120     alsabar.bar:set_ticks(ticks)
121     alsabar.bar:set_ticks_size(ticks_size)
122     alsabar.bar:set_vertical(vertical)
123
124     function alsabar.update()
125         -- Get mixer control contents
126         local mixer = read_pipe(string.format("%s get %s", alsabar.cmd, alsabar.channel))
127
128         -- Capture mixer control state:          [5%] ... ... [on]
129         local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
130
131         volu = tonumber(volu) or 0
132         if mute == "" then mute = "off"
133
134         if alsabar._current_level ~= volu or alsabar._status ~= mute then
135
136             alsabar._current_level = volu
137             alsabar._status = mute
138
139             alsabar.bar:set_value(alsabar._current_level / 100)
140
141             if not mute and 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 = volu
154             volume_now.status = mute
155
156             settings()
157         end
158     end
159
160     alsabar.bar:buttons (awful.util.table.join (
161           awful.button ({}, 1, function()
162             awful.util.spawn(alsabar.mixer)
163           end),
164           awful.button ({}, 3, function()
165             awful.util.spawn(string.format("%s set %s toggle", alsabar.cmd, alsabar.channel))
166             alsabar.update()
167           end),
168           awful.button ({}, 4, function()
169             awful.util.spawn(string.format("%s set %s %s+", alsabar.cmd, alsabar.channel, alsabar.step))
170             alsabar.update()
171           end),
172           awful.button ({}, 5, function()
173             awful.util.spawn(string.format("%s set %s %s-", alsabar.cmd, alsabar.channel, alsabar.step))
174             alsabar.update()
175           end)
176     ))
177
178     timer_id = string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel)
179
180     newtimer(timer_id, timeout, alsabar.update)
181
182     return alsabar
183 end
184
185 return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end })