testsAndMisc/linux_configuration/scripts/single_use/utils/volume_control.sh
Krzysztof kuhy Rudnicki 038e08d2be feat: split oversized modules for 500-line limit, fix kasa coverage gap
Split diet_guard/_gatelock.py, wake_alarm/_alarm.py, and the
usage_report.py/_usage_report_parsing.py pair into focused
sub-modules so every Python file is <= 500 lines, satisfying
test_file_length.py. Install python-kasa into .venv (declared in
requirements but missing after the 3.13->3.14 venv upgrade),
fixing 8 failing smart_plug tests and restoring 100% coverage.

Also includes prior in-progress work from the working tree: the
wake_alarm Progress/View/Hardware field-grouping refactor,
brother_printer query module + tests, diet_guard foodbank/state/cli
updates, new shared coerce/logging_setup helpers, morning_routine
orchestrator tweaks, dwm window-manager config, gaming scripts, and
misc maintenance/digital-wellbeing script updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 07:19:37 +02:00

68 lines
2.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# ============================================================================
# volume_control.sh — adjust PulseAudio volume / mute via pactl
# ============================================================================
# Single entry point for media-key bindings in i3 and dwm. Shows a transient
# desktop notification (best-effort). Replaces the long-missing ~/volume_control.sh
# that both window-manager configs referenced.
#
# Usage: volume_control.sh {up|down|mute|micmute}
# up raise output volume by VOLUME_STEP% (default 5) and unmute
# down lower output volume by VOLUME_STEP% and unmute
# mute toggle output (sink) mute
# micmute toggle input (source) mute
# ============================================================================
set -euo pipefail
readonly SINK="@DEFAULT_SINK@"
readonly SOURCE="@DEFAULT_SOURCE@"
readonly STEP="${VOLUME_STEP:-5}"
# Best-effort notification; never fail the binding if no daemon is running.
notify() {
command -v notify-send >/dev/null 2>&1 || return 0
# Collapse repeated volume popups into one via a synchronous hint.
notify-send -t 1200 -h string:x-canonical-private-synchronous:volume \
"$1" "$2" 2>/dev/null || true
}
# First percentage pactl reports for the default sink (e.g. "45%").
current_sink_volume() {
pactl get-sink-volume "$SINK" 2>/dev/null | grep -oE '[0-9]+%' | head -1 || true
}
case "${1:-}" in
up)
pactl set-sink-mute "$SINK" 0
pactl set-sink-volume "$SINK" "+${STEP}%"
notify "Volume" "$(current_sink_volume)"
;;
down)
pactl set-sink-mute "$SINK" 0
pactl set-sink-volume "$SINK" "-${STEP}%"
notify "Volume" "$(current_sink_volume)"
;;
mute)
pactl set-sink-mute "$SINK" toggle
if pactl get-sink-mute "$SINK" 2>/dev/null | grep -q yes; then
notify "Volume" "Muted"
else
notify "Volume" "$(current_sink_volume)"
fi
;;
micmute)
pactl set-source-mute "$SOURCE" toggle
if pactl get-source-mute "$SOURCE" 2>/dev/null | grep -q yes; then
notify "Microphone" "Muted"
else
notify "Microphone" "On"
fi
;;
*)
echo "Usage: $(basename "$0") {up|down|mute|micmute}" >&2
exit 1
;;
esac