#!/usr/bin/env bash # # Copyright (c) 2016-2020 Thomas Goldbrunner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # VERSION="2.1.0" RELEASE_DATE="2020-11-10" __is_playing() { dbus-send --print-reply --dest="$INTERFACE.$1" "$OBJPATH" \ "$GET_PROPERTIES" string:"$INTERFACE.Player" string:'PlaybackStatus' 2>/dev/null | \ grep 'Playing' &> /dev/null } __pause_player() { dbus-send --print-reply --dest="$INTERFACE.$1" "$OBJPATH" \ "$INTERFACE.Player.Pause" &> /dev/null PAUSED_PLAYER="$1" } __resume_player() { dbus-send --print-reply --dest="$INTERFACE.$1" "$OBJPATH" \ "$INTERFACE.Player.Play" &> /dev/null } # Array of supported desktops used to specify DBUS interface declare -A desktops=( ["Unity"]="interface='com.canonical.Unity.Session'" ["GNOME"]="gnome" ["ubuntu:GNOME"]="gnome" ["X-Cinnamon"]="cinnamon" ["MATE"]="mate" ["KDE"]="freedesktop" ["pop:GNOME"]="gnome" ["XFCE"]="xfce" ) # D-Bus interface, object path and method needed to control MPRIS players INTERFACE="org.mpris.MediaPlayer2" OBJPATH="/org/mpris/MediaPlayer2" GET_PROPERTIES="org.freedesktop.DBus.Properties.Get" # variable to check, whether we paused on lock PAUSED_PLAYER="none" # variable indicating whether to use playerctl PLAYERCTL=false # parse command line options while (( "$#" )); do case "$1" in -h|--help) echo "Usage: \$ pause-on-lock [option]" echo "" echo "Options:" echo "" echo " -p|--player NAME set the player to pause on lock" echo " -c|--playerctl enable playerctl support" echo " -h|--help print this help text and exit" echo " -v|--version print version information and exit" echo "" echo "For more information visit https://github.com/folixg/pause-on-lock" echo "" exit 0 ;; -v|--version) echo "This is pause-on-lock $VERSION (released $RELEASE_DATE)" exit 0 ;; -p|--player) USER_PLAYER="$2" shift 2 ;; -c|--playerctl) # check if playerctl is available on the system if [ ! "$(playerctl --version 2>/dev/null)" ]; then echo "Error: failed to execute playerctl." exit 1 fi PLAYERCTL=true shift ;; *) echo "Error: Unknown flag $1" echo "Run \"pause-on-lock --help\" for help." exit 1 ;; esac done # Players we want to control players=("$USER_PLAYER" rhythmbox spotify) if [ "${desktops[$XDG_CURRENT_DESKTOP]}" == "" ]; then echo "Error: Unsupported desktop. Supported desktops are Unity, GNOME, Cinnamon, Mate and KDE." exit 1 fi if [ "$XDG_CURRENT_DESKTOP" == "Unity" ] ; then DBUS_LOCK="${desktops[$XDG_CURRENT_DESKTOP]}" LOCK_SIGNAL="Locked" UNLOCK_SIGNAL="Unlocked" else DBUS_LOCK="interface='org.${desktops[$XDG_CURRENT_DESKTOP]}.ScreenSaver',member='ActiveChanged'" LOCK_SIGNAL="true" UNLOCK_SIGNAL="false" fi dbus-monitor --session "type='signal',$DBUS_LOCK" | \ ( while true; do read -r X # pause on lock if echo "$X" | grep "$LOCK_SIGNAL" &> /dev/null; then # with playerctl if $PLAYERCTL; then # get list of running players read -r -a players <<< "$(playerctl --list-all)" # check whether a player is playing for player in "${players[@]}" do if [ "$(playerctl --player="$player" status)" = "Playing" ] ; then # and pause it playerctl --player="$player" pause PAUSED_PLAYER=$player fi done # without playerctl else for player in "${players[@]}"; do if __is_playing "$player"; then __pause_player "$player" fi done fi fi # resume on unlock if echo "$X" | grep "$UNLOCK_SIGNAL" &> /dev/null; then # did we pause on lock? if [ "$PAUSED_PLAYER" != "none" ] ; then __resume_player "$PAUSED_PLAYER" fi # reset PAUSED_PLAYER variable PAUSED_PLAYER="none" fi done )