From 27182f3196245e4f85be538f7a70308c1b73333b Mon Sep 17 00:00:00 2001 From: facetoe Date: Sun, 12 Oct 2014 18:14:47 +0800 Subject: [PATCH 1/2] Added optional volume_bar and colors. --- i3pystatus/pulseaudio/__init__.py | 37 ++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/i3pystatus/pulseaudio/__init__.py b/i3pystatus/pulseaudio/__init__.py index 6a0a018..de4b246 100644 --- a/i3pystatus/pulseaudio/__init__.py +++ b/i3pystatus/pulseaudio/__init__.py @@ -1,9 +1,11 @@ +from i3pystatus.core.color import ColorRangeModule +from i3pystatus.core.util import make_vertical_bar, make_bar from .pulse import * from i3pystatus import Module +import subprocess - -class PulseAudio(Module): +class PulseAudio(Module, ColorRangeModule): """ Shows volume of default PulseAudio sink (output). @@ -13,13 +15,19 @@ class PulseAudio(Module): * `{db}` — volume in decibels relative to 100 %, i.e. 100 % = 0 dB, 50 % = -18 dB, 0 % = -infinity dB (the literal value for -infinity is `-∞`) * `{muted}` — the value of one of the `muted` or `unmuted` settings + * `{volume_bar}` — unicode bar showing volume """ settings = ( "format", ("format_muted", "optional format string to use when muted"), "muted", "unmuted", - "color_muted", "color_unmuted" + "color_muted", "color_unmuted", + ("step", "percentage to increment volume on scroll"), + ("bar_type", "type of volume bar. Allowed values are 'vertical' or 'horizontal'"), + ("multi_colors", "whether or not to change the color from " + "'color_muted' to 'color_unmuted' based on volume percentage"), + ("vertical_bar_width", "how many characters wide the vertical volume_bar should be") ) muted = "M" @@ -29,6 +37,11 @@ class PulseAudio(Module): color_muted = "#FF0000" color_unmuted = "#FFFFFF" + step = 5 + multi_colors = False + bar_type = 'vertical' + vertical_bar_width = 2 + def init(self): """Creates context, when context is ready context_notify_cb is called""" # Wrap callback methods in appropriate ctypefunc instances so @@ -51,6 +64,8 @@ class PulseAudio(Module): pa_context_connect(context, None, 0, None) pa_threaded_mainloop_start(_mainloop) + self.colors = self.get_hex_color_range(self.color_muted, self.color_unmuted, 100) + def request_update(self, context): """Requests a sink info update (sink_info_cb is called)""" pa_operation_unref(pa_context_get_sink_info_by_name( @@ -101,19 +116,31 @@ class PulseAudio(Module): volume_db = int(volume_db) muted = self.muted if sink_info.mute else self.unmuted - color = self.color_muted if sink_info.mute else self.color_unmuted + + if self.multi_colors and not sink_info.mute: + color = self.get_gradient(volume_percent, self.colors) + else: + color = self.color_muted if sink_info.mute else self.color_unmuted if muted and self.format_muted is not None: output_format = self.format_muted else: output_format = self.format + if self.bar_type == 'vertical': + volume_bar = make_vertical_bar(volume_percent, self.vertical_bar_width) + elif self.bar_type == 'horizontal': + volume_bar = make_bar(volume_percent) + else: + raise Exception("bar_type must be 'vertical' or 'horizontal'") + self.output = { "color": color, "full_text": output_format.format( muted=muted, volume=volume_percent, - db=volume_db), + db=volume_db, + volume_bar=volume_bar), } def on_leftclick(self): From 556eed9fde3871fec8ba258b6a27489d7407af2d Mon Sep 17 00:00:00 2001 From: facetoe Date: Sun, 12 Oct 2014 18:22:35 +0800 Subject: [PATCH 2/2] Added toggle mute/unmute on left click, increment/decrement volume on scroll. --- i3pystatus/pulseaudio/__init__.py | 33 +++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/i3pystatus/pulseaudio/__init__.py b/i3pystatus/pulseaudio/__init__.py index de4b246..2888f91 100644 --- a/i3pystatus/pulseaudio/__init__.py +++ b/i3pystatus/pulseaudio/__init__.py @@ -1,3 +1,5 @@ +import os +import shutil from i3pystatus.core.color import ColorRangeModule from i3pystatus.core.util import make_vertical_bar, make_bar from .pulse import * @@ -9,6 +11,8 @@ class PulseAudio(Module, ColorRangeModule): """ Shows volume of default PulseAudio sink (output). + Requires amixer for toggling mute and incrementing/decrementing volume on scroll. + Available formatters: * `{volume}` — volume in percent (0...100) @@ -34,6 +38,8 @@ class PulseAudio(Module, ColorRangeModule): unmuted = "" format = "♪: {volume}" format_muted = None + currently_muted = False + has_amixer = False color_muted = "#FF0000" color_unmuted = "#FFFFFF" @@ -66,6 +72,9 @@ class PulseAudio(Module, ColorRangeModule): self.colors = self.get_hex_color_range(self.color_muted, self.color_unmuted, 100) + # Check that we have amixer for toggling mute/unmute and incrementing/decrementing volume + self.has_amixer = shutil.which('alsamixer') is not None + def request_update(self, context): """Requests a sink info update (sink_info_cb is called)""" pa_operation_unref(pa_context_get_sink_info_by_name( @@ -109,6 +118,7 @@ class PulseAudio(Module, ColorRangeModule): sink_info = sink_info_p.contents volume_percent = int(100 * sink_info.volume.values[0] / 0x10000) volume_db = pa_sw_volume_to_dB(sink_info.volume.values[0]) + self.currently_muted = sink_info.mute if volume_db == float('-Infinity'): volume_db = "-∞" @@ -144,6 +154,25 @@ class PulseAudio(Module, ColorRangeModule): } def on_leftclick(self): - import subprocess - subprocess.Popen(["pavucontrol"]) + + def on_rightclick(self): + if self.has_amixer: + command = "amixer -q -D pulse sset Master " + if self.currently_muted: + command += 'unmute' + else: + command += 'mute' + subprocess.Popen(command.split()) + + def on_upscroll(self): + if self.has_amixer: + command = "amixer -q -D pulse sset Master %s%%+" % self.step + subprocess.Popen(command.split()) + + def on_downscroll(self): + if self.has_amixer: + command = "amixer -q -D pulse sset Master %s%%-" % self.step + subprocess.Popen(command.split()) + +