Add pipewire and bluetooth scripts for polybar modules
This commit is contained in:
parent
f183b22ee8
commit
502dd59723
670
scripts/pulseaudio-control.bash
Executable file
670
scripts/pulseaudio-control.bash
Executable file
|
@ -0,0 +1,670 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
##################################################################
|
||||
# Polybar Pulseaudio Control #
|
||||
# https://github.com/marioortizmanero/polybar-pulseaudio-control #
|
||||
##################################################################
|
||||
|
||||
# Deprecated values, to be removed in a next release. This is kept around to
|
||||
# be displayed for users using it in custom FORMAT
|
||||
# shellcheck disable=SC2034
|
||||
ICON_SINK="Replaced by ICON_NODE, see https://github.com/marioortizmanero/polybar-pulseaudio-control/releases/tag/v3.0.0"
|
||||
SINK_NICKNAME="Replaced by NODE_NICKNAME, see https://github.com/marioortizmanero/polybar-pulseaudio-control/releases/tag/v3.0.0"
|
||||
|
||||
# Defaults for configurable values, expected to be set by command-line arguments
|
||||
AUTOSYNC="no"
|
||||
COLOR_MUTED="%{F#6b6b6b}"
|
||||
ICON_MUTED=
|
||||
ICON_NODE=
|
||||
NODE_TYPE="output"
|
||||
NOTIFICATIONS="no"
|
||||
OSD="no"
|
||||
NODE_NICKNAMES_PROP=
|
||||
VOLUME_STEP=2
|
||||
VOLUME_MAX=130
|
||||
LISTEN_TIMEOUT=0.05
|
||||
# shellcheck disable=SC2016
|
||||
FORMAT='$VOL_ICON ${VOL_LEVEL}% $ICON_NODE $NODE_NICKNAME'
|
||||
declare -A NODE_NICKNAMES
|
||||
declare -a ICONS_VOLUME
|
||||
declare -a NODE_BLACKLIST
|
||||
|
||||
# Special variable: within the script, pactl, grep, and awk commands are used
|
||||
# on sinks or sources, depending on NODE_TYPE.
|
||||
#
|
||||
# The commands are almost always the same, except for the sink/source part.
|
||||
# In order to reduce duplication, this variable is used for commands that behave
|
||||
# the same, regardless of the NODE_TYPE.
|
||||
#
|
||||
# Having only the "radix" (ink/ource) and omitting the first letter enables us
|
||||
# to use that single variable:
|
||||
#
|
||||
# S-ink , s-ink , s-ink -s, S-ink -s
|
||||
# S-ource, s-ource, s-ource-s, S-ource-s
|
||||
SINK_OR_SOURCE="ink"
|
||||
|
||||
# Environment & global constants for the script
|
||||
export LC_ALL=C # Some calls depend on English outputs of pactl
|
||||
END_COLOR="%{F-}" # For Polybar colors
|
||||
|
||||
|
||||
# Saves the currently default node into a variable named `curNode`. It will
|
||||
# return an error code when pulseaudio isn't running.
|
||||
function getCurNode() {
|
||||
if ! pactl info &>/dev/null; then return 1; fi
|
||||
local curNodeName
|
||||
|
||||
curNodeName=$(pactl info | awk "/Default S${SINK_OR_SOURCE}: / {print \$3}")
|
||||
curNode=$(pactl list "s${SINK_OR_SOURCE}s" | grep -B 4 -E "Name: $curNodeName\$" | sed -nE "s/^S${SINK_OR_SOURCE} #([0-9]+)$/\1/p")
|
||||
}
|
||||
|
||||
|
||||
# Saves the node passed by parameter's volume into a variable named `VOL_LEVEL`.
|
||||
function getCurVol() {
|
||||
VOL_LEVEL=$(pactl list "s${SINK_OR_SOURCE}s" | grep -A 15 -E "^S${SINK_OR_SOURCE} #$1\$" | grep 'Volume:' | grep -E -v 'Base Volume:' | awk -F : '{print $3; exit}' | grep -o -P '.{0,3}%' | sed 's/.$//' | tr -d ' ')
|
||||
}
|
||||
|
||||
|
||||
# Saves the name of the node passed by parameter into a variable named
|
||||
# `nodeName`.
|
||||
function getNodeName() {
|
||||
nodeName=$(pactl list "s${SINK_OR_SOURCE}s" short | awk -v sink="$1" "{ if (\$1 == sink) {print \$2} }")
|
||||
portName=$(pactl list "s${SINK_OR_SOURCE}s" | grep -e "S${SINK_OR_SOURCE} #" -e 'Active Port: ' | sed -n "/^S${SINK_OR_SOURCE} #$1\$/,+1p" | awk '/Active Port: / {print $3}')
|
||||
}
|
||||
|
||||
|
||||
# Saves the name to be displayed for the node passed by parameter into a
|
||||
# variable called `NODE_NICKNAME`.
|
||||
# If a mapping for the node name exists, that is used. Otherwise, the string
|
||||
# "Node #<index>" is used.
|
||||
function getNickname() {
|
||||
getNodeName "$1"
|
||||
unset NODE_NICKNAME
|
||||
|
||||
if [ -n "$nodeName" ] && [ -n "$portName" ] && [ -n "${NODE_NICKNAMES[$nodeName/$portName]}" ]; then
|
||||
NODE_NICKNAME="${NODE_NICKNAMES[$nodeName/$portName]}"
|
||||
elif [ -n "$nodeName" ] && [ -n "${NODE_NICKNAMES[$nodeName]}" ]; then
|
||||
NODE_NICKNAME="${NODE_NICKNAMES[$nodeName]}"
|
||||
elif [ -n "$nodeName" ]; then
|
||||
# No exact match could be found, try a Glob Match
|
||||
for glob in "${!NODE_NICKNAMES[@]}"; do
|
||||
# shellcheck disable=SC2053 # Disable Shellcheck warning for Glob-Matching
|
||||
if [[ "$nodeName/$portName" == $glob ]] || [[ "$nodeName" == $glob ]]; then
|
||||
NODE_NICKNAME="${NODE_NICKNAMES[$glob]}"
|
||||
# Cache that result for next time
|
||||
NODE_NICKNAMES["$nodeName"]="$NODE_NICKNAME"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$NODE_NICKNAME" ] && [ -n "$nodeName" ] && [ -n "$NODE_NICKNAMES_PROP" ]; then
|
||||
getNicknameFromProp "$NODE_NICKNAMES_PROP" "$nodeName"
|
||||
# Cache that result for next time
|
||||
NODE_NICKNAMES["$nodeName"]="$NODE_NICKNAME"
|
||||
elif [ -z "$NODE_NICKNAME" ]; then
|
||||
NODE_NICKNAME="S${SINK_OR_SOURCE} #$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Gets node nickname based on a given property.
|
||||
function getNicknameFromProp() {
|
||||
local nickname_prop="$1"
|
||||
local for_name="$2"
|
||||
|
||||
NODE_NICKNAME=
|
||||
while read -r property value; do
|
||||
case "$property" in
|
||||
Name:)
|
||||
node_name="$value"
|
||||
unset node_desc
|
||||
;;
|
||||
"$nickname_prop")
|
||||
if [ "$node_name" != "$for_name" ]; then
|
||||
continue
|
||||
fi
|
||||
NODE_NICKNAME="${value:3:-1}"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done < <(pactl list "s${SINK_OR_SOURCE}s")
|
||||
}
|
||||
|
||||
# Saves the status of the node passed by parameter into a variable named
|
||||
# `IS_MUTED`.
|
||||
function getIsMuted() {
|
||||
IS_MUTED=$(pactl list "s${SINK_OR_SOURCE}s" | grep -E "^S${SINK_OR_SOURCE} #$1\$" -A 15 | awk '/Mute: / {print $2}')
|
||||
}
|
||||
|
||||
|
||||
# Saves all the sink inputs of the sink passed by parameter into a string
|
||||
# named `sinkInputs`.
|
||||
function getSinkInputs() {
|
||||
sinkInputs=$(pactl list sink-inputs | grep -B 4 "Sink: $1" | sed -nE "s/^Sink Input #([0-9]+)\$/\1/p")
|
||||
}
|
||||
|
||||
|
||||
# Saves all the source outputs of the source passed by parameter into a string
|
||||
# named `sourceOutputs`.
|
||||
function getSourceOutputs() {
|
||||
sourceOutputs=$(pactl list source-outputs | grep -B 4 "Source: $1" | sed -nE "s/^Source Output #([0-9]+)\$/\1/p")
|
||||
}
|
||||
|
||||
|
||||
function volUp() {
|
||||
# Obtaining the current volume from pulseaudio into $VOL_LEVEL.
|
||||
if ! getCurNode; then
|
||||
echo "PulseAudio not running"
|
||||
return 1
|
||||
fi
|
||||
getCurVol "$curNode"
|
||||
local maxLimit=$((VOLUME_MAX - VOLUME_STEP))
|
||||
|
||||
# Checking the volume upper bounds so that if VOLUME_MAX was 100% and the
|
||||
# increase percentage was 3%, a 99% volume would top at 100% instead
|
||||
# of 102%. If the volume is above the maximum limit, nothing is done.
|
||||
if [ "$VOL_LEVEL" -le "$VOLUME_MAX" ] && [ "$VOL_LEVEL" -ge "$maxLimit" ]; then
|
||||
pactl "set-s${SINK_OR_SOURCE}-volume" "$curNode" "$VOLUME_MAX%"
|
||||
elif [ "$VOL_LEVEL" -lt "$maxLimit" ]; then
|
||||
pactl "set-s${SINK_OR_SOURCE}-volume" "$curNode" "+$VOLUME_STEP%"
|
||||
fi
|
||||
|
||||
if [ $OSD = "yes" ]; then showOSD "$curNode"; fi
|
||||
if [ $AUTOSYNC = "yes" ]; then volSync; fi
|
||||
}
|
||||
|
||||
|
||||
function volDown() {
|
||||
# Pactl already handles the volume lower bounds so that negative values
|
||||
# are ignored.
|
||||
if ! getCurNode; then
|
||||
echo "PulseAudio not running"
|
||||
return 1
|
||||
fi
|
||||
pactl "set-s${SINK_OR_SOURCE}-volume" "$curNode" "-$VOLUME_STEP%"
|
||||
|
||||
if [ $OSD = "yes" ]; then showOSD "$curNode"; fi
|
||||
if [ $AUTOSYNC = "yes" ]; then volSync; fi
|
||||
}
|
||||
|
||||
|
||||
function volSync() {
|
||||
# This will only be called if $AUTOSYNC is `yes`.
|
||||
|
||||
if ! getCurNode; then
|
||||
echo "PulseAudio not running"
|
||||
return 1
|
||||
fi
|
||||
|
||||
getCurVol "$curNode"
|
||||
|
||||
if [[ "$NODE_TYPE" = "output" ]]; then
|
||||
getSinkInputs "$curNode"
|
||||
|
||||
# Every output found in the active sink has their volume set to the
|
||||
# current one.
|
||||
for each in $sinkInputs; do
|
||||
pactl "set-sink-input-volume" "$each" "$VOL_LEVEL%"
|
||||
done
|
||||
else
|
||||
getSourceOutputs "$curNode"
|
||||
|
||||
# Every input found in the active source has their volume set to the
|
||||
# current one.
|
||||
for each in $sourceOutputs; do
|
||||
pactl "set-source-output-volume" "$each" "$VOL_LEVEL%"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function volMute() {
|
||||
# Switch to mute/unmute the volume with pactl.
|
||||
if ! getCurNode; then
|
||||
echo "PulseAudio not running"
|
||||
return 1
|
||||
fi
|
||||
if [ "$1" = "toggle" ]; then
|
||||
getIsMuted "$curNode"
|
||||
if [ "$IS_MUTED" = "yes" ]; then
|
||||
pactl "set-s${SINK_OR_SOURCE}-mute" "$curNode" "no"
|
||||
else
|
||||
pactl "set-s${SINK_OR_SOURCE}-mute" "$curNode" "yes"
|
||||
fi
|
||||
elif [ "$1" = "mute" ]; then
|
||||
pactl "set-s${SINK_OR_SOURCE}-mute" "$curNode" "yes"
|
||||
elif [ "$1" = "unmute" ]; then
|
||||
pactl "set-s${SINK_OR_SOURCE}-mute" "$curNode" "no"
|
||||
fi
|
||||
|
||||
if [ $OSD = "yes" ]; then showOSD "$curNode"; fi
|
||||
}
|
||||
|
||||
|
||||
function nextNode() {
|
||||
# The final nodes list, removing the blacklisted ones from the list of
|
||||
# currently available nodes.
|
||||
if ! getCurNode; then
|
||||
echo "PulseAudio not running"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Obtaining a tuple of node indexes after removing the blacklisted devices
|
||||
# with their name.
|
||||
nodes=()
|
||||
local i=0
|
||||
while read -r line; do
|
||||
index=$(echo "$line" | cut -f1)
|
||||
name=$(echo "$line" | cut -f2)
|
||||
|
||||
# If it's in the blacklist, continue the main loop. Otherwise, add
|
||||
# it to the list.
|
||||
for node in "${NODE_BLACKLIST[@]}"; do
|
||||
# shellcheck disable=SC2053 # Disable Shellcheck warning for Glob-Matching
|
||||
if [[ "$name" == $node ]]; then
|
||||
continue 2
|
||||
fi
|
||||
done
|
||||
|
||||
nodes[i]="$index"
|
||||
i=$((i + 1))
|
||||
done < <(pactl list short "s${SINK_OR_SOURCE}s" | sort -n)
|
||||
|
||||
# If the resulting list is empty, nothing is done
|
||||
if [ ${#nodes[@]} -eq 0 ]; then return; fi
|
||||
|
||||
# If the current node is greater or equal than last one, pick the first
|
||||
# node in the list. Otherwise just pick the next node avaliable.
|
||||
local newNode
|
||||
if [ "$curNode" -ge "${nodes[-1]}" ]; then
|
||||
newNode=${nodes[0]}
|
||||
else
|
||||
for node in "${nodes[@]}"; do
|
||||
if [ "$curNode" -lt "$node" ]; then
|
||||
newNode=$node
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# The new node is set
|
||||
pactl "set-default-s${SINK_OR_SOURCE}" "$newNode"
|
||||
|
||||
# Move all audio threads to new node
|
||||
local inputs
|
||||
|
||||
if [[ "$NODE_TYPE" = "output" ]]; then
|
||||
inputs="$(pactl list short sink-inputs | cut -f 1)"
|
||||
for i in $inputs; do
|
||||
pactl move-sink-input "$i" "$newNode"
|
||||
done
|
||||
else
|
||||
outputs="$(pactl list short source-outputs | cut -f 1)"
|
||||
for i in $outputs; do
|
||||
pactl move-source-output "$i" "$newNode"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $NOTIFICATIONS = "yes" ]; then
|
||||
getNickname "$newNode"
|
||||
|
||||
if command -v dunstify &>/dev/null; then
|
||||
notify="dunstify --replace 201839192"
|
||||
else
|
||||
notify="notify-send"
|
||||
fi
|
||||
$notify "PulseAudio" "Changed $NODE_TYPE to $NODE_NICKNAME" --icon=audio-headphones-symbolic &
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# This function assumes that PulseAudio is already running. It only supports
|
||||
# KDE OSDs for now. It will show a system message with the status of the
|
||||
# node passed by parameter, or the currently active one by default.
|
||||
function showOSD() {
|
||||
if [ -z "$1" ]; then
|
||||
curNode="$1"
|
||||
else
|
||||
getCurNode
|
||||
fi
|
||||
getCurVol "$curNode"
|
||||
getIsMuted "$curNode"
|
||||
qdbus org.kde.kded /modules/kosd showVolume "$VOL_LEVEL" "$IS_MUTED"
|
||||
}
|
||||
|
||||
|
||||
function listen() {
|
||||
# If this is the first time start by printing the current state. Otherwise,
|
||||
# directly wait for events. This is to prevent the module being empty until
|
||||
# an event occurs.
|
||||
output
|
||||
|
||||
# Listen for changes and immediately create new output for the bar.
|
||||
# This is faster than having the script on an interval.
|
||||
pactl subscribe 2>/dev/null | grep --line-buffered -e "on \(card\|s${SINK_OR_SOURCE}\|server\)" | {
|
||||
while read -r; do
|
||||
# Output the new state
|
||||
output
|
||||
|
||||
# Read all stdin to flush unwanted pending events, i.e. if there are
|
||||
# 15 events at the same time (100ms window), output is only called
|
||||
# twice.
|
||||
read -r -d '' -t "$LISTEN_TIMEOUT" -n 10000
|
||||
|
||||
# After the 100ms waiting time, output again the state, as it may
|
||||
# have changed if the user did an action during the 100ms window.
|
||||
output
|
||||
done
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function output() {
|
||||
if ! getCurNode; then
|
||||
echo "PulseAudio not running"
|
||||
return 1
|
||||
fi
|
||||
getCurVol "$curNode"
|
||||
getIsMuted "$curNode"
|
||||
|
||||
# Fixed volume icons over max volume
|
||||
local iconsLen=${#ICONS_VOLUME[@]}
|
||||
if [ "$iconsLen" -ne 0 ]; then
|
||||
local volSplit=$((VOLUME_MAX / iconsLen))
|
||||
for i in $(seq 1 "$iconsLen"); do
|
||||
if [ $((i * volSplit)) -ge "$VOL_LEVEL" ]; then
|
||||
VOL_ICON="${ICONS_VOLUME[$((i-1))]}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
VOL_ICON=""
|
||||
fi
|
||||
|
||||
getNickname "$curNode"
|
||||
|
||||
# Showing the formatted message
|
||||
if [ "$IS_MUTED" = "yes" ]; then
|
||||
# shellcheck disable=SC2034
|
||||
VOL_ICON=$ICON_MUTED
|
||||
content="$(eval echo "$FORMAT")"
|
||||
if [ -n "$COLOR_MUTED" ]; then
|
||||
echo "${COLOR_MUTED}${content}${END_COLOR}"
|
||||
else
|
||||
echo "$content"
|
||||
fi
|
||||
else
|
||||
eval echo "$FORMAT"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function usage() {
|
||||
echo "\
|
||||
Usage: $0 [OPTION...] ACTION
|
||||
|
||||
Terminology: A node represents either a sink (output) or source (input).
|
||||
|
||||
Options:
|
||||
--autosync | --no-autosync
|
||||
Whether to maintain same volume for all programs.
|
||||
Default: \"$AUTOSYNC\"
|
||||
--color-muted <rrggbb>
|
||||
Color in which to format when muted.
|
||||
Pass empty string to disable.
|
||||
Default: \"${COLOR_MUTED:4:-1}\"
|
||||
--notifications | --no-notifications
|
||||
Whether to show notifications when changing nodes.
|
||||
Default: \"$NOTIFICATIONS\"
|
||||
--osd | --no-osd
|
||||
Whether to display KDE's OSD message.
|
||||
Default: \"$OSD\"
|
||||
--icon-muted <icon>
|
||||
Icon to use when muted.
|
||||
Default: none
|
||||
--icon-node <icon>
|
||||
Icon to use for node.
|
||||
Default: none
|
||||
--format <string>
|
||||
Use a format string to control the output.
|
||||
Remember to pass this argument wrapped in single quotes (\`'\`) instead
|
||||
of double quotes (\`\"\`) to avoid your shell from evaluating the
|
||||
variables early.
|
||||
Available variables:
|
||||
* \$VOL_ICON
|
||||
* \$VOL_LEVEL
|
||||
* \$ICON_NODE
|
||||
* \$NODE_NICKNAME
|
||||
* \$IS_MUTED (yes/no)
|
||||
Default: '$FORMAT'
|
||||
--icons-volume <icon>[,<icon>...]
|
||||
Icons for volume, from lower to higher.
|
||||
Default: none
|
||||
--node-type <node_type>
|
||||
Whether to consider PulseAudio sinks (output) or sources (input).
|
||||
All the operations of pulseaudio-control will apply to one of the two.
|
||||
Pass \`input\` for the sources, e.g. a microphone.
|
||||
Pass \`output\` for the sinks, e.g. speakers, headphones.
|
||||
Default: \"$NODE_TYPE\"
|
||||
--volume-max <int>
|
||||
Maximum volume to which to allow increasing.
|
||||
Default: \"$VOLUME_MAX\"
|
||||
--volume-step <int>
|
||||
Step size when inc/decrementing volume.
|
||||
Default: \"$VOLUME_STEP\"
|
||||
--node-blacklist <name>[,<name>...]
|
||||
Nodes to ignore when switching. You can use globs. Don't forget to
|
||||
quote the string when using globs, to avoid unwanted shell glob
|
||||
extension.
|
||||
Default: none
|
||||
--node-nicknames-from <prop>
|
||||
pactl property to use for node names, unless overridden by
|
||||
--node-nickname. Its possible values are listed under the 'Properties'
|
||||
key in the output of \`pactl list sinks\` and \`pactl list sources\`.
|
||||
Default: none
|
||||
--node-nickname <name>:<nick>
|
||||
Nickname to assign to given node name, taking priority over
|
||||
--node-nicknames-from. May be given multiple times, and 'name' is
|
||||
exactly as listed in the output of \`pactl list sinks short | cut -f2\`
|
||||
and \`pactl list sources short | cut -f2\`.
|
||||
Note that you can also specify a port name for the node with
|
||||
\`<name>/<port>\`.
|
||||
It is also possible to use glob matching to match node and port names.
|
||||
Exact matches are prioritized. Don't forget to quote the string when
|
||||
using globs, to avoid unwanted shell glob extension.
|
||||
Default: none
|
||||
--listen-timeout-secs
|
||||
The listen command updates the output as soon as it receives an event
|
||||
from PulseAudio. However, events are often accompanied by many other
|
||||
useless ones, which may result in unnecessary consecutive output
|
||||
updates. This script buffers the following events until a timeout is
|
||||
reached to avoid this scenario, which lessens the CPU load on events.
|
||||
However, this may result in noticeable latency when performing many
|
||||
actions quickly (e.g., updating the volume with the mouse wheel). You
|
||||
can specify what timeout to use to control the responsiveness, in
|
||||
seconds.
|
||||
Default: \"$LISTEN_TIMEOUT\"
|
||||
|
||||
Actions:
|
||||
help display this message and exit
|
||||
output print the PulseAudio status once
|
||||
listen listen for changes in PulseAudio to automatically update
|
||||
this script's output
|
||||
up, down increase or decrease the default node's volume
|
||||
mute, unmute mute or unmute the default node's audio
|
||||
togmute switch between muted and unmuted
|
||||
next-node switch to the next available node
|
||||
sync synchronize all the output streams volume to be the same as
|
||||
the current node's volume
|
||||
|
||||
Author:
|
||||
Mario Ortiz Manero
|
||||
More info on GitHub:
|
||||
https://github.com/marioortizmanero/polybar-pulseaudio-control"
|
||||
}
|
||||
|
||||
# Obtains the value for an option and returns 1 if no shift is needed.
|
||||
function getOptVal() {
|
||||
if [[ "$1" = *=* ]]; then
|
||||
val="${1//*=/}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
val="$2"
|
||||
}
|
||||
|
||||
# Parsing the options from the arguments
|
||||
while [[ "$1" = --* ]]; do
|
||||
unset arg
|
||||
unset val
|
||||
|
||||
arg="$1"
|
||||
case "$arg" in
|
||||
--autosync)
|
||||
AUTOSYNC=yes
|
||||
;;
|
||||
--no-autosync)
|
||||
AUTOSYNC=no
|
||||
;;
|
||||
--color-muted|--colour-muted)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
COLOR_MUTED="%{F#$val}"
|
||||
;;
|
||||
--notifications)
|
||||
NOTIFICATIONS=yes
|
||||
;;
|
||||
--no-notifications)
|
||||
NOTIFICATIONS=no
|
||||
;;
|
||||
--osd)
|
||||
OSD=yes
|
||||
;;
|
||||
--no-osd)
|
||||
OSD=no
|
||||
;;
|
||||
--icon-muted)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
ICON_MUTED="$val"
|
||||
;;
|
||||
--icon-node)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
# shellcheck disable=SC2034
|
||||
ICON_NODE="$val"
|
||||
;;
|
||||
--icons-volume)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
IFS=, read -r -a ICONS_VOLUME <<< "${val//[[:space:]]/}"
|
||||
;;
|
||||
--volume-max)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
VOLUME_MAX="$val"
|
||||
;;
|
||||
--volume-step)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
VOLUME_STEP="$val"
|
||||
;;
|
||||
--node-blacklist)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
IFS=, read -r -a NODE_BLACKLIST <<< "${val//[[:space:]]/}"
|
||||
;;
|
||||
--node-nicknames-from)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
NODE_NICKNAMES_PROP="$val"
|
||||
;;
|
||||
--node-nickname)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
NODE_NICKNAMES["${val//:*/}"]="${val//*:}"
|
||||
;;
|
||||
--format)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
FORMAT="$val"
|
||||
;;
|
||||
--node-type)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
if [[ "$val" != "output" && "$val" != "input" ]]; then
|
||||
echo "node-type must be 'output' or 'input', got '$val'" >&2
|
||||
exit 1
|
||||
fi
|
||||
NODE_TYPE="$val"
|
||||
SINK_OR_SOURCE=$([ "$NODE_TYPE" == "output" ] && echo "ink" || echo "ource")
|
||||
;;
|
||||
--listen-timeout-secs)
|
||||
if getOptVal "$@"; then shift; fi
|
||||
LISTEN_TIMEOUT="$val"
|
||||
;;
|
||||
# Deprecated options, to be removed in a next release
|
||||
--icon-sink)
|
||||
echo "Replaced by --icon-node, see https://github.com/marioortizmanero/polybar-pulseaudio-control/releases/tag/v3.0.0" >&2
|
||||
exit 1
|
||||
;;
|
||||
--sink-blacklist)
|
||||
echo "Replaced by --node-blacklist, see https://github.com/marioortizmanero/polybar-pulseaudio-control/releases/tag/v3.0.0" >&2
|
||||
exit 1
|
||||
;;
|
||||
--sink-nicknames-from)
|
||||
echo "Replaced by --node-nicknames-from, see https://github.com/marioortizmanero/polybar-pulseaudio-control/releases/tag/v3.0.0" >&2
|
||||
exit 1
|
||||
;;
|
||||
--sink-nickname)
|
||||
echo "Replaced by --node-nickname, see https://github.com/marioortizmanero/polybar-pulseaudio-control/releases/tag/v3.0.0" >&2
|
||||
exit 1
|
||||
;;
|
||||
# Undocumented because the `help` action already exists, but makes the
|
||||
# help message more accessible.
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unrecognised option: $arg" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Parsing the action from the arguments
|
||||
case "$1" in
|
||||
up)
|
||||
volUp
|
||||
;;
|
||||
down)
|
||||
volDown
|
||||
;;
|
||||
togmute)
|
||||
volMute toggle
|
||||
;;
|
||||
mute)
|
||||
volMute mute
|
||||
;;
|
||||
unmute)
|
||||
volMute unmute
|
||||
;;
|
||||
sync)
|
||||
volSync
|
||||
;;
|
||||
listen)
|
||||
listen
|
||||
;;
|
||||
next-node)
|
||||
nextNode
|
||||
;;
|
||||
output)
|
||||
output
|
||||
;;
|
||||
help)
|
||||
usage
|
||||
;;
|
||||
# Deprecated action, to be removed in a next release
|
||||
next-sink)
|
||||
echo "Replaced by next-node, see https://github.com/marioortizmanero/polybar-pulseaudio-control/releases/tag/v3.0.0" >&2
|
||||
exit 1
|
||||
;;
|
||||
"")
|
||||
echo "No action specified. Run \`$0 help\` for more information." >&2
|
||||
;;
|
||||
*)
|
||||
echo "Unrecognised action: $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
64
scripts/system-bluetooth-bluetoothctl.sh
Executable file
64
scripts/system-bluetooth-bluetoothctl.sh
Executable file
|
@ -0,0 +1,64 @@
|
|||
#!/bin/sh
|
||||
|
||||
bluetooth_print() {
|
||||
bluetoothctl | while read -r; do
|
||||
if [ "$(systemctl is-active "bluetooth.service")" = "active" ]; then
|
||||
if bluetoothctl show | grep -q "Powered: no"; then
|
||||
echo " "
|
||||
else
|
||||
printf ' '
|
||||
|
||||
devices_paired=$(bluetoothctl devices Paired | grep Device | cut -d ' ' -f 2)
|
||||
counter=0
|
||||
|
||||
for device in $devices_paired; do
|
||||
device_info=$(bluetoothctl info "$device")
|
||||
|
||||
if echo "$device_info" | grep -q "Connected: yes"; then
|
||||
device_alias=$(echo "$device_info" | grep "Alias" | cut -d ' ' -f 2-)
|
||||
|
||||
if [ $counter -gt 0 ]; then
|
||||
printf ", %s" "$device_alias"
|
||||
else
|
||||
printf " %s" "$device_alias"
|
||||
fi
|
||||
|
||||
counter=$((counter + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
printf '\n'
|
||||
fi
|
||||
else
|
||||
echo " "
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
bluetooth_toggle() {
|
||||
if bluetoothctl show | grep -q "Powered: no"; then
|
||||
bluetoothctl power on >> /dev/null
|
||||
sleep 1
|
||||
|
||||
devices_paired=$(bluetoothctl devices Paired | grep Device | cut -d ' ' -f 2)
|
||||
echo "$devices_paired" | while read -r line; do
|
||||
bluetoothctl connect "$line" >> /dev/null
|
||||
done
|
||||
else
|
||||
devices_paired=$(bluetoothctl devices Paired | grep Device | cut -d ' ' -f 2)
|
||||
echo "$devices_paired" | while read -r line; do
|
||||
bluetoothctl disconnect "$line" >> /dev/null
|
||||
done
|
||||
|
||||
bluetoothctl power off >> /dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
--toggle)
|
||||
bluetooth_toggle
|
||||
;;
|
||||
*)
|
||||
bluetooth_print
|
||||
;;
|
||||
esac
|
Loading…
Reference in a new issue