#!/bin/sh # SPDX-License-Identifier: AGPL-3.0-only # Copyright 2022 Sxmo Contributors export PATH="${XDG_CONFIG_HOME:-$HOME/.config}/sxmo/hooks:/usr/share/sxmo/default_hooks:$PATH" # shellcheck source=configs/default_hooks/sxmo_hook_icons.sh . sxmo_hook_icons.sh . sxmo_common.sh set -e notifyvol() { vol="$1" if [ "-" = "$vol" ]; then vol="$(cat)" fi if [ "muted" = "$vol" ]; then vol=0 fi if [ -z "$SXMO_WOB_DISABLE" ]; then printf "%s\n" "$vol" > "$XDG_RUNTIME_DIR"/sxmo.obsock else notify-send -r 999 "$icon_audio Volume $vol" fi } # adjust *output* vol/mute volup() { pactl set-sink-volume @DEFAULT_SINK@ +"${1:-5}%" } voldown() { pactl set-sink-volume @DEFAULT_SINK@ -"${1:-5}%" } voltogglemute() { pactl set-sink-mute @DEFAULT_SINK@ toggle } volismuted() { pactl get-sink-mute @DEFAULT_SINK@ | grep -q "Mute: yes" } volget() { if volismuted; then printf "muted" else pactl get-sink-volume @DEFAULT_SINK@ | head -n1 | cut -d'/' -f2 | sed 's/ //g' | sed 's/\%//' fi } volset() { pactl set-sink-volume @DEFAULT_SINK@ "$1"% } # adjust *input* vol/mute micvolup() { pactl set-source-volume @DEFAULT_SOURCE@ +"${1:-5}%" } micvoldown() { pactl set-source-volume @DEFAULT_SOURCE@ -"${1:-5}%" } mictogglemute() { pactl set-source-mute @DEFAULT_SOURCE@ toggle } micismuted() { pactl get-source-mute @DEFAULT_SOURCE@ | grep -q "Mute: yes" } micvolget() { if micismuted; then printf "muted" else pactl get-source-volume @DEFAULT_SOURCE@ | head -n1 | cut -d'/' -f2 | sed 's/ //g' | sed 's/\%//' fi } micvolset() { pactl set-source-volume @DEFAULT_SOURCE@ "$1"% } # set the *active port* for output deviceset() { if pactl --format=json list sinks | jq -e ".[] | select(.name == \"$(pactl get-default-sink)\") | .ports[] | select(.name == \"[Out] $1\")" >/dev/null 2>&1; then pactl set-sink-port @DEFAULT_SINK@ "[Out] $1" else prof="$(pactl --format=json list cards | jq -r ".[] | . as \$c | .ports[\"[Out] $1\"]? | select(. != null and .availability != \"not available\") | .profiles[] | select(\$c.profiles[.].available == true) | \"\(\$c.name) \(.)\"" | head -n1)" if [ -n "$prof" ]; then card="$(printf "%s" "$prof" | cut -f1)" profile="$(printf "%s" "$prof" | cut -f2)" pactl set-card-profile "$card" "$profile" fi fi } # set the *active port* for input devicesetinput() { pactl set-source-port @DEFAULT_SOURCE@ "[In] $1" } # get the *active port* for input devicegetinput() { [ -z "$1" ] && default_source="$(pactl get-default-source)" || default_source="$1" pactl --format=json list sources | jq -r ".[] | select(.name == \"$default_source\") | .active_port" | sed 's/\[In] //' } # get the *active port* for output deviceget() { [ -z "$1" ] && default_sink="$(pactl get-default-sink)" || default_sink="$1" pactl --format=json list sinks | jq -r ".[] | select(.name == \"$default_sink\") | .active_port" | sed 's/\[Out] //' } # get the default sink devicegetdefaultsink() { pactl get-default-sink } # get the default source devicegetdefaultsource() { pactl get-default-source } sourceset() { pactl set-default-source "$1" } sinkset() { pactl set-default-sink "$1" } profileset() { pactl set-card-profile "$1" "$2" } # get a list of sinks _sinkssubmenu() { [ -z "$1" ] && default_sink="$(pactl get-default-sink)" || default_sink="$1" pactl --format=json list sinks | jq -r '.[] | .name, .description' | while read -r line; do name="$line" read -r description if [ "$default_sink" = "$name" ]; then printf "%s %s %s ^ sinkset %s\n" "$icon_chk" "$icon_spk" "$description" "$name" else printf " %s %s ^ sinkset %s\n" "$icon_spk" "$description" "$name" fi done } # get a list of output ports _outportssubmenu() { [ -z "$1" ] && default_sink="$(pactl get-default-sink)" || default_sink="$1" active_out_port="$(deviceget "$default_sink")" pactl --format=json list cards | jq -r ".[] | .ports | to_entries[] | select((.key | startswith(\"[Out] \")) and .value.availability != \"not available\") | .key" | sed 's/\[Out] //' | while read -r line; do [ "$active_out_port" = "$line" ] && icon="$icon_ton" || icon="$icon_tof" printf " %s %s ^ deviceset %s " "$icon" "$line" "$line" done } # get a list of input sources _sourcessubmenu() { [ -z "$1" ] && default_source="$(pactl get-default-source)" || default_source="$1" pactl --format=json list sources | jq -r '.[] | select (.monitor_source == "") | .name, .description' | while read -r line; do name="$line" read -r description if [ "$default_source" = "$name" ]; then printf "%s %s %s ^ sourceset %s\n" "$icon_chk" "$icon_mic" "$description" "$name" else printf " %s %s ^ sourceset %s\n" "$icon_mic" "$description" "$name" fi done } _cardssubmenu() { cards="$(pactl -f json list cards)" printf "%s\n" "$cards" | jq -r '.[] | [.name, .active_profile] | @tsv' | \ while IFS=" " read -r card active_profile; do printf "%s %s\n" "$icon_nte" "$card" printf "%s\n" "$cards" | jq -r ".[] | select(.name == \"$card\") | .profiles | to_entries[] | select(.value.available) | [.key, .value.description] | @tsv" | \ while IFS=" " read -r profile desc; do if [ "$profile" = "$active_profile" ]; then printf "%s %s ^ true\n" "$icon_chk" "$desc" else printf " %s ^ profileset %s \"%s\"\n" "$desc" "$card" "$profile" fi done done } # get a list of input ports _inportssubmenu() { # if the Headset is NOT plugged in, then do not display Headset # as a option, as clicking on it causes pulse to unset the source!! [ -z "$1" ] && default_source="$(pactl get-default-source)" || default_source="$1" active_in_port="$(devicegetinput "$default_source")" pactl --format=json list sources | jq -r ".[] | select(.name == \"$default_source\" ) | .ports[] | select(.availability != \"not available\" ) | .name" | sed 's/\[In] //' | while read -r line; do [ "$active_in_port" = "$line" ] && icon="$icon_ton" || icon="$icon_tof" printf " %s %s ^ devicesetinput %s\n" "$icon" "$line" "$line" done } _ringmodesubmenu() { if [ -f "$XDG_CONFIG_HOME"/sxmo/.noring ]; then printf " %s Ring ^ rm -f \"$XDG_CONFIG_HOME\"/sxmo/.noring\n" "$icon_tof" else printf " %s Ring ^ touch \"$XDG_CONFIG_HOME\"/sxmo/.noring\n" "$icon_ton" fi if [ -f "$XDG_CONFIG_HOME"/sxmo/.novibrate ]; then printf " %s Vibrate ^ rm -f \"$XDG_CONFIG_HOME\"/sxmo/.novibrate\n" "$icon_tof" else printf " %s Vibrate ^ touch \"$XDG_CONFIG_HOME\"/sxmo/.novibrate\n" "$icon_ton" fi if [ -f "$XDG_CONFIG_HOME"/sxmo/.busy ]; then end="$(cat "$XDG_CONFIG_HOME"/sxmo/.busy)" if [ -n "$end" ] && [ "$(date +%s)" -gt "$end" ]; then rm "$XDG_CONFIG_HOME"/sxmo/.busy fi fi if [ -f "$XDG_CONFIG_HOME"/sxmo/.busy ]; then printf " %s Busy ^ rm -f \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_ton" else printf " %s Busy ^ touch \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tof" printf " %s Busy for 15 min ^ date '+%%s+15*60' | bc > \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tmr" printf " %s Busy for 30 min ^ date '+%%s+30*60' | bc > \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tmr" printf " %s Busy for 1 hour ^ date '+%%s+60*60' | bc > \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tmr" printf " %s Busy for 2 hour ^ date '+%%s+2*60*60' | bc > \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tmr" printf " %s Busy for 3 hour ^ date '+%%s+3*60*60' | bc > \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tmr" fi } menuchoices() { cur_vol="$(volget)" cur_mic_vol="$(micvolget)" default_sink_name="$(devicegetdefaultsink)" default_source_name="$(devicegetdefaultsource)" grep . <