From 889c01eb6d6c540be73bd9ed0c23628344291d50 Mon Sep 17 00:00:00 2001 From: paul-loedige Date: Sun, 13 Dec 2020 00:44:48 +0100 Subject: [PATCH] added microphone widget --- qtile/.config/qtile/config.py | 129 ++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/qtile/.config/qtile/config.py b/qtile/.config/qtile/config.py index a8a66c2..0e1bde8 100644 --- a/qtile/.config/qtile/config.py +++ b/qtile/.config/qtile/config.py @@ -1,3 +1,4 @@ +import re import os import subprocess import psutil @@ -170,6 +171,8 @@ floating_layout = layout.Floating( #endregion #region Custom_Widgets + +#region Custom_Memory class MemoryC(widget.base.ThreadedPollText): orientations = widget.base.ORIENTATION_HORIZONTAL defaults = [ @@ -204,6 +207,118 @@ class MemoryC(widget.base.ThreadedPollText): return self.format.format(**val) #endregion +#region Microphone_Widget +re_vol = re.compile(r'\[(\d?\d?\d?)%\]') +BUTTON_MUTE = 1 +class Mic(widget.base._TextBox): + """ + Custom Microphone widget + """ + orientations = widget.base.ORIENTATION_HORIZONTAL + defaults = [ + ("cardid", None, "Card Id"), + ("device", "default", "Device Name"), + ("channel", "Capture", "Channel"), + ("padding", 3, "Padding left and right. Calculated if None."), + ("update_interval", 0.2, "Update time in seconds."), + ("theme_path", None, "Path of the icons"), + ("emoji", False, "Use emoji to display volume states, only if ``theme_path`` is not set." + "The specified font needs to contain the correct unicode characters."), + ("mute_command", None, "Mute command"), + ("volume_app", None, "App to control volume"), + ("volume_up_command", None, "Volume up command"), + ("volume_down_command", None, "Volume down command"), + ("get_volume_command", None, "Command to get the current volume"), + ("step", 2, "Volume change for up an down commands in percentage." + "Only used if ``volume_up_command`` and ``volume_down_command`` are not set.") + ] + + def __init__(self, **config): + widget.base._TextBox.__init__(self, '0', width=bar.CALCULATED, **config) + self.add_defaults(Mic.defaults) + if self.theme_path: + self.length_type = bar.STATIC + self.length = 0 + self.surfaces = {} + self.volume = None + + def timer_setup(self): + self.timeout_add(self.update_interval, self.update) + if self.theme_path: + self.setup_images() + + def create_amixer_command(self, *args): + cmd = ['amixer'] + cmd.extend([x for x in args]) + return cmd + + def button_press(self, x, y, button): + if button == BUTTON_MUTE: + if self.mute_command is not None: + subprocess.call(self.mute_command, shell=True) + else: + subprocess.call(self.create_amixer_command('-q', + 'sset', + self.channel, + 'toggle')) + self.draw() + + def update(self): + vol = self.get_volume() + if vol != self.volume: + self.volume = vol + # Update the underlying canvas size before actually attempting + # to figure out how big it is and draw it. + self._update_drawer() + self.bar.draw() + self.timeout_add(self.update_interval, self.update) + + def _update_drawer(self): + if self.emoji: + if self.volume > 0: + self.text = '' + elif self.volume <= 0: + self.text = '' + else: + if self.volume == -1: + self.text = 'M' + else: + self.text = '{}%'.format(self.volume) + def get_volume(self): + try: + get_volume_cmd = self.create_amixer_command('sget', + self.channel) + + if self.get_volume_command: + get_volume_cmd = self.get_volume_command + + mixer_out = self.call_process(get_volume_cmd) + except subprocess.CalledProcessError: + return -1 + + if '[off]' in mixer_out: + return -1 + + volgroups = re_vol.search(mixer_out) + if volgroups: + return int(volgroups.groups()[0]) + else: + # this shouldn't happen + return -1 + + def draw(self): + if self.theme_path: + self.drawer.draw(offsetx=self.offset, width=self.length) + else: + widget.base._TextBox.draw(self) + + def cmd_mute(self): + # Emulate button press. + self.button_press(0, 0, BUTTON_MUTE) +#endregion + +#endregion + #region widgets #region Powerline @@ -278,6 +393,18 @@ def vloume_widget(prev_color,color,size,fontsize): fontsize=fontsize, padding=0 ), + Mic( + foreground=dark_foreground_color, + background=color, + emoji=True, + fontsize=fontsize, + ), + Mic( + foreground=dark_foreground_color, + background=color, + fontsize=fontsize, + padding=0 + ), widget.TextBox(" ",background=color), ] #endregion @@ -456,6 +583,8 @@ cursor_warp = False auto_fullscreen = True focus_on_window_activation = "smart" + + # XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this # string besides java UI toolkits; you can see several discussions on the # mailing lists, GitHub issues, and other WM documentation that suggest setting