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

version 1.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 local awful        = require("awful")
10 local beautiful    = require("beautiful")
11 local naughty      = require("naughty")
12
13 local io           = io
14 local math         = { modf  = math.modf }
15 local string       = { match = string.match,
16                        rep   = string.rep }
17 local tonumber     = tonumber
18
19 local setmetatable = setmetatable
20
21 -- ALSA volume bar
22 -- lain.widgets.alsabar
23 local alsabar =
24 {
25   channel = "Master",
26   step = "5%",
27
28   colors =
29   {
30      background = beautiful.bg_normal,
31      mute   = "#EB8F8F",
32      unmute = "#A4CE8A"
33   },
34
35   mixer = terminal .. " -e alsamixer",
36
37   notifications =
38   {
39      font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")),
40      font_size = "11",
41      bar_size = 18 -- Awesome default
42   },
43
44   _current_level = 0,
45   _muted = false
46 }
47
48 function alsabar:notify()
49         local preset =
50         {
51       title = "", text = "",
52       timeout = 3,
53       font = alsabar.notifications.font .. " " .. alsabar.notifications.font_size,
54       fg = beautiful.fg_focus
55         }
56
57         if alsabar._muted then
58                 preset.title = alsabar.channel .. " - Muted"
59         else
60                 preset.title = alsabar.channel .. " - " .. alsabar._current_level * 100 .. "%"
61         end
62
63   local int = math.modf(alsabar._current_level * alsabar.notifications.bar_size)
64   preset.text = "[" .. string.rep("|", int)
65                 .. string.rep(" ", alsabar.notifications.bar_size - int) .. "]"
66
67   if alsabar._notify ~= nil then
68                 alsabar._notify = naughty.notify ({ replaces_id = alsabar._notify.id,
69                                                        preset = preset })
70         else
71                 alsabar._notify = naughty.notify ({ preset = preset })
72         end
73 end
74
75 function worker(args)
76     local args = args or {}
77     local width = args.width or 63
78     local height = args.heigth or 1
79     local ticks = args.ticks or true
80     local ticks_size = args.ticks_size or 7
81     local vertical = args.vertical or false
82     alsabar.channel = args.channel or alsabar.channel
83     alsabar.step = args.step or alsabar.step
84     alsabar.colors = args.colors or alsabar.colors
85     alsabar.notifications = args.notifications or alsabar.notifications
86
87     alsabar.bar = awful.widget.progressbar()
88     alsabar.bar:set_background_color(alsabar.colors.background)
89     alsabar.bar:set_color(alsabar.colors.unmute)
90     alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
91     alsabar.bar:set_width(width)
92     alsabar.bar:set_height(height)
93     alsabar.bar:set_ticks(ticks)
94     alsabar.bar:set_ticks_size(ticks_size)
95
96     if vertical then
97         alsabar.bar:set_vertical(true)
98     end
99
100     local myvolumebarupdate = function()
101         -- Get mixer control contents
102         local f = io.popen("amixer get " .. alsabar.channel)
103         local mixer = f:read("*all")
104         f:close()
105
106         -- Capture mixer control state:          [5%] ... ... [on]
107         local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
108         -- Handle mixers without data
109         if volu == nil then
110            volu = 0
111            mute = "off"
112         end
113
114         alsabar._current_level = tonumber(volu) / 100
115         alsabar.bar:set_value(alsabar._current_level)
116
117         if mute == "" and volu == "0" or mute == "off"
118         then
119             alsabar._muted = true
120             alsabar.tooltip:set_text (" [Muted] ")
121             alsabar.bar:set_color(alsabar.colors.mute)
122         else
123             alsabar._muted = false
124             alsabar.tooltip:set_text(" " .. alsabar.channel .. ": " .. volu .. "% ")
125             alsabar.bar:set_color(alsabar.colors.unmute)
126         end
127     end
128
129     local myvolumebartimer = timer({ timeout = 5 })
130     myvolumebartimer:connect_signal("timeout", myvolumebarupdate)
131     myvolumebartimer:start()
132     myvolumebartimer:emit_signal("timeout")
133
134     alsabar.bar:buttons (awful.util.table.join (
135           awful.button ({}, 1, function()
136             awful.util.spawn(alsabar.mixer)
137           end),
138           awful.button ({}, 3, function()
139             awful.util.spawn("amixer sset " .. alsabar.channel .. " toggle")
140             myvolumebarupdate()
141           end),
142           awful.button ({}, 4, function()
143             awful.util.spawn("amixer sset " .. alsabar.channel .. " "
144                               .. alsabar.step .. "+")
145             myvolumebarupdate()
146           end),
147           awful.button ({}, 5, function()
148             awful.util.spawn("amixer sset " .. alsabar.channel .. " "
149                               .. alsabar.step .. "-")
150             myvolumebarupdate()
151           end)
152     ))
153
154     return { widget = alsabar.bar,
155              channel = alsabar.channel, 
156              step = alsabar.step,
157              notify = function() 
158                          myvolumebarupdate()
159                          alsabar.notify()
160                        end
161            }
162 end
163
164 return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end })