diff --git a/dotfiles/lib/bin/get_sink_input_by_pid.sh b/dotfiles/lib/bin/get_sink_input_by_pid.sh new file mode 100755 index 00000000..e62e63e2 --- /dev/null +++ b/dotfiles/lib/bin/get_sink_input_by_pid.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env zsh + + +get_sink_input_info.hs | jq 'select(.application_process_id == "'"$thePID"'")' diff --git a/dotfiles/lib/bin/get_sink_input_info.hs b/dotfiles/lib/bin/get_sink_input_info.hs new file mode 100755 index 00000000..d5c0fcce --- /dev/null +++ b/dotfiles/lib/bin/get_sink_input_info.hs @@ -0,0 +1,39 @@ +#!/usr/bin/env runhaskell +{-# LANGUAGE FlexibleContexts, AllowAmbiguousTypes #-} + +import Control.Monad +import Data.Aeson +import qualified Data.ByteString as B +import qualified Data.Text.Lazy.IO as T +import qualified Data.Text.Lazy.Encoding as T +import Data.List +import Data.List.Split +import Data.Maybe +import qualified Data.Map as M +import Data.Text (unpack) +import System.Process +import Text.Printf +import Text.Regex.Posix +import System.Exit + +main :: IO () +main = do + out <- getSinkText + let sinkTexts = splitOn "\nSink " out + getMatches txt regex = getAllTextMatches $ txt =~ regex :: [String] + getPair regex txt = frth $ (txt =~ regex :: (String, String, String, [String])) + frth (_,_,_,a:b:_) = (map dotToUnderscore a, b) + dotToUnderscore '.' = '_' + dotToUnderscore c = c + getPairs txt regex = map (getPair regex) $ getMatches txt regex + getSinkMap' txt = M.union (M.fromList $ getPairs txt propertyRegex) + (M.fromList $ getPairs txt fieldRegex) + getSinkMap txt = M.insert "sink_input_id" (getSinkNumber txt) $ getSinkMap' txt + getSinkNumber txt = case txt =~ "Input #([0-9]*)" :: (String, String, String, [String]) of + (_,_,_,a) -> head a + mapM_ (T.putStrLn . T.decodeUtf8 . encode . getSinkMap) sinkTexts + where getSinkText = do + (_, txt, _) <- readCreateProcessWithExitCode (shell "pactl list sink-inputs") "" + return txt + propertyRegex = "^[\t\n ]+([^\n:]*) = \"([^\n]*)\"" + fieldRegex = "^[\t\n ]+(.*?): ([^\n ]*)" diff --git a/dotfiles/lib/bin/mute_current_window.sh b/dotfiles/lib/bin/mute_current_window.sh new file mode 100755 index 00000000..46fb96da --- /dev/null +++ b/dotfiles/lib/bin/mute_current_window.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env zsh + +thePID="$(xprop _NET_WM_PID -id $(xdotool getactivewindow) | grep -Eo '[0-9]*')" +sinkInfo="$(pashowinputbypid $thePID)" +sinkID="$(echo $sinkInfo | jq -r .sink_input_id)" +muted="$(echo $sinkInfo | jq -r .Mute)" +if [[ $muted == *"no"* ]]; then + newState="1" +else + newState="0" +fi + +echo "$sinkID" + +pactl set-sink-input-mute "$sinkID" "$newState" diff --git a/dotfiles/lib/bin/set_volume.sh b/dotfiles/lib/bin/set_volume.sh index f3edc19e..a7371c00 100755 --- a/dotfiles/lib/bin/set_volume.sh +++ b/dotfiles/lib/bin/set_volume.sh @@ -1,5 +1,4 @@ #!/usr/bin/env zsh pulseaudio-ctl "$@" - -volnoti-show "$(pavolume)" +pashowvolume diff --git a/dotfiles/lib/shellenv/linux.sh b/dotfiles/lib/shellenv/linux.sh index a5bcad92..95c74d59 100644 --- a/dotfiles/lib/shellenv/linux.sh +++ b/dotfiles/lib/shellenv/linux.sh @@ -1,7 +1,9 @@ +is_osx && return + command_exists 'open' || command_exists 'xdg-open' && alias open='xdg-open' pasink () { - pacmd list-sinks | grep '* index' | get_cols ' -1' + pacmd list-sinks | grep '\* index' | get_cols ' -1' } pasink() { @@ -10,7 +12,22 @@ pasink() { pavolume () { pacmd list-sinks | - awk '/^\s+name: /{indefault = $2 == "<'$(pasink)'>"} + awk '/^\s+name: /{indefault = $2 == "<'"$(pasink)"'>"} /^\s+volume: / && indefault {print $5; exit}' - +} + +paismuted () { + pactl list sinks | grep "$(pasink)" -A 10 | grep Mute | grep -q yes +} + +pashowvolume () { + if paismuted; then + volnoti-show -m + else + volnoti-show "$(pavolume)" + fi +} + +pashowinputbypid () { + get_sink_input_info.hs | jq 'select(.application_process_id == "'"$1"'")' }