diff --git a/recipes.mdwn b/recipes.mdwn index bd4d955..e41fbd3 100644 --- a/recipes.mdwn +++ b/recipes.mdwn @@ -22,6 +22,7 @@ to improve your Awesome setup. * [Battery Indicator (UPower)](https://github.com/stefano-m/awesome-power_widget) * [[Google Play Music Desktop Player|recipes/gpmdp]] * [Set of simple widgets](https://github.com/streetturtle/awesome-wm-widgets) - widgets for battery, cpu, brightness, volume, email, etc. +* [Microphone state](../recipes/mic) ## Libraries diff --git a/recipes/mic.lua b/recipes/mic.lua new file mode 100644 index 0000000..a277f3c --- /dev/null +++ b/recipes/mic.lua @@ -0,0 +1,164 @@ +--[[ + + Licensed under GNU General Public License v2 + * (c) 2021, bzgec + + +# Microphone state widget/watcher +This widget can be used to display the current microphone status. + +## Requirements +- `amixer` - this command is used to get and toggle microphone state + +## Usage +- Download [mic.lua](https://awesomewm.org/recipes/mic.lua) file and put it into awesome's + folder (like `~/.config/awesome/widgets/mic.lua`) +- Add widget to `theme.lua`: + + ```lua + local widgets = { + mic = require("widgets/mic"), + } + theme.mic = widgets.mic({ + timeout = 10, + settings = function(self) + if self.state == "muted" then + self.widget:set_image(theme.widget_micMuted) + else + self.widget:set_image(theme.widget_micUnmuted) + end + end + }) + local widget_mic = wibox.widget { theme.mic.widget, layout = wibox.layout.align.horizontal } + ``` + +- Create a shortcut to toggle microphone state (add to `rc.lua`): + + ```lua + -- Toggle microphone state + awful.key({ modkey, "Shift" }, "m", + function () + beautiful.mic:toggle() + end, + {description = "Toggle microphone (amixer)", group = "Hotkeys"} + ), + ``` + +- You can also add a command to mute the microphone state on boot. Add this to your `rc.lua`: + + ```lua + -- Mute microphone on boot + beautiful.mic:mute() + ``` + +--]] + + +local awful = require("awful") +local naughty = require("naughty") +local gears = require("gears") +local wibox = require("wibox") + +local function factory(args) + local args = args or {} + + local mic = { + widget = args.widget or wibox.widget.imagebox(), + settings = args.settings or function(self) end, + timeout = args.timeout or 10, + timer = gears.timer, + state = "", + } + + function mic:mute() + awful.spawn.easy_async_with_shell("amixer set Capture nocap", + function() + self:update() + end + ) + end + + function mic:unmute() + awful.spawn.easy_async_with_shell("amixer set Capture cap", + function() + self:update() + end + ) + end + + function mic:toggle() + awful.spawn.easy_async_with_shell("amixer set Capture toggle", + function() + self:update() + end + ) + end + + function mic:pressed(button) + if button == 1 then + self:toggle() + end + end + + function mic:update() + -- Check that timer has started + if self.timer.started then + self.timer:emit_signal("timeout") + end + end + + -- Read `amixer get Capture` command and try to `grep` all "[on]" lines. + -- - If there are lines with "[on]" then assume microphone is "unmuted". + -- - If there are NO lines with "[on]" then assume microphone is "muted". + mic, mic.timer = awful.widget.watch( + "bash -c \"amixer get Capture | grep '\\[on\\]'\"", + mic.timeout, + function(self, stdout, stderr, exitreason, exitcode) + local current_micState = "error" + + if exitcode == 1 then + -- Exit code 1 - no line selected + current_micState = "muted" + elseif exitcode == 0 then + -- Exit code 0 - a line is selected + current_micState = "unmuted" + else + -- Other exit code (2) - error occurred + current_micState = "error" + end + + -- Compare new and old state + if current_micState ~= self.state then + if current_micState == "muted" then + naughty.notify({preset=naughty.config.presets.normal, + title="mic widget info", + text='muted'}) + elseif current_micState == "unmuted" then + naughty.notify({preset=naughty.config.presets.normal, + title="mic widget info", + text='unmuted'}) + else + naughty.notify({preset=naughty.config.presets.critical, + title="mic widget error", + text='Error on "amixer get Capture | grep \'\\[on\\]\'"'}) + end + + -- Store new microphone state + self.state = current_micState + end + + -- Call user/theme defined function + self:settings() + end, + mic -- base_widget (passed in callback function as first parameter) + ) + + -- add mouse click + mic.widget:connect_signal("button::press", function(c, _, _, button) + mic:pressed(button) + end) + + return mic +end + +return factory diff --git a/recipes/mic.mdwn b/recipes/mic.mdwn new file mode 100644 index 0000000..a381e9e --- /dev/null +++ b/recipes/mic.mdwn @@ -0,0 +1,46 @@ +# Microphone state widget/watcher +This widget can be used to display the current microphone status. + +## Requirements +- `amixer` - this command is used to get and toggle microphone state + +## Usage +- Download [mic.lua](https://awesomewm.org/recipes/mic.lua) file and put it into awesome's + folder (like `~/.config/awesome/widgets/mic.lua`) +- Add widget to `theme.lua`: + + ```lua + local widgets = { + mic = require("widgets/mic"), + } + theme.mic = widgets.mic({ + timeout = 10, + settings = function(self) + if self.state == "muted" then + self.widget:set_image(theme.widget_micMuted) + else + self.widget:set_image(theme.widget_micUnmuted) + end + end + }) + local widget_mic = wibox.widget { theme.mic.widget, layout = wibox.layout.align.horizontal } + ``` + +- Create a shortcut to toggle microphone state (add to `rc.lua`): + + ```lua + -- Toggle microphone state + awful.key({ modkey, "Shift" }, "m", + function () + beautiful.mic:toggle() + end, + {description = "Toggle microphone (amixer)", group = "Hotkeys"} + ), + ``` + +- You can also add a command to mute the microphone state on boot. Add this to your `rc.lua`: + + ```lua + -- Mute microphone on boot + beautiful.mic:mute() + ```