My collection of plugins for the Qtile window manager.
git clone https://mcol.xyz/code/qtools
Log | Files | Refs | README

commit e63caf9573872fb0691bfdbea9c680bdd922b40b
parent 4405950bcca9a4c38b890580861d1a9bb0ffee4b
Author: mcol <mcol@posteo.net>
Date:   Mon, 17 Feb 2020 18:36:01 +0000

amixer Notifier: allow use of Master channel exclusively for muting

Diffstat:
Mqtools/amixer/amixer.py | 70++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 50 insertions(+), 20 deletions(-)

diff --git a/qtools/amixer/amixer.py b/qtools/amixer/amixer.py @@ -21,51 +21,81 @@ from qtools import Notifier class Volume(Notifier): + """ + This Notifier can be used to control ALSA mixer volume and muting, sending + notifications when operations are performed. + + The 'mixer' option should be set to the name of the ALSA mixer you use to control + the volume. By default this will also be used for mute/unmute operations. + Alternatively, if you use the Master mixer for muting instead of the mixer used for + volume control, set 'mute_master' to true. + """ defaults = [ ('summary', 'Volume', 'Notification summary.'), ('mixer', 'Master', 'ALSA mixer to control.'), ('interval', 5, 'Percentage interval to change volume by.'), + ('mute_master', False, 'Use the Master mixer for mute operations'), ] def __init__(self, **config): Notifier.__init__(self, **config) self.add_defaults(Volume.defaults) + if self.mute_master and self.mixer == 'Master': + self.mute_master = False def increase(self, qtile=None): - volume = self._run(f'{self.interval}%+') + stdout = self._run(['set', self.mixer, f'{self.interval}%+']) + volume = self._get_volume(stdout) self.show(self.interval * round(volume / self.interval)) def decrease(self, qtile=None): - volume = self._run(f'{self.interval}%-') + stdout = self._run(['set', self.mixer, f'{self.interval}%-']) + volume = self._get_volume(stdout) self.show(self.interval * round(volume / self.interval)) def toggle(self, qtile=None): - volume = self._run('toggle') - self.show(self.interval * round(volume / self.interval)) + stdout = self._run(['set', 'Master' if self.mute_master else self.mixer, 'toggle']) + if self._get_mute(stdout): + self.show('Muted') + else: + if self.mute_master: + stdout = self._run(['get', self.mixer]) + volume = self._get_volume(stdout) + self.show(self.interval * round(volume / self.interval)) def mute(self, qtile=None): - self._run('mute') + self._run(['set', 'Master' if self.mute_master else self.mixer, 'mute']) self.show('Muted') def unmute(self, qtile=None): - volume = self._run('unmute') - self.show(volume) + stdout = self._run( + ['set', 'Master' if self.mute_master else self.mixer, 'unmute'] + ) + volume = self._get_volume(self._run(['get', self.mixer])) + self.show(self.interval * round(volume / self.interval)) + + def _get_mute(self, stdout): + if len(stdout) == 5: + if stdout[4].decode().split()[5][1:-1] == 'on': + return False + else: + return True + logger.warning('Output from amixer needs decoding') - def _run(self, setting): + def _get_volume(self, stdout): + if len(stdout) == 5: + return int(stdout[4].decode().split()[3][1:-2]) + if len(stdout) == 7: + return int(stdout[5].decode().split()[4][1:-2]) + logger.warning('Output from amixer needs decoding') + + def _run(self, args): + cmd = ['amixer'] + cmd.extend(args) try: - output = subprocess.run( - ['amixer', 'set', self.mixer, setting], - stdout=subprocess.PIPE, - ) + output = subprocess.run(cmd, stdout=subprocess.PIPE) stdout = output.stdout.splitlines() except subprocess.CalledProcessError as err: logger.error(err.output.decode()) return - - if len(stdout) == 5: - volume = int(stdout[4].decode().split()[3][1:-2]) - elif len(stdout) == 7: - volume = int(stdout[5].decode().split()[4][1:-2]) - else: - logger.warning('Output from amixer needs decoding') - return volume + return stdout