aboutsummaryrefslogtreecommitdiffstats
path: root/bin/lid-switch-action
diff options
context:
space:
mode:
Diffstat (limited to 'bin/lid-switch-action')
-rwxr-xr-xbin/lid-switch-action198
1 files changed, 198 insertions, 0 deletions
diff --git a/bin/lid-switch-action b/bin/lid-switch-action
new file mode 100755
index 0000000..a2779b7
--- /dev/null
+++ b/bin/lid-switch-action
@@ -0,0 +1,198 @@
+#!/bin/bash
+# What action to take on closing the laptop lid,
+# depending on whether a screen is attached or not.
+# This implies setting HandleLidSwitch=ignore in /etc/systemd/logind.conf
+# Call this script from /etc/acpi/handler.sh (or other properly set up script
+# for handling button/lid acpi event) with parameter 0 and 1 for close and open respectively
+
+set -e -u
+
+# Find current Xsession user through loginctl list-sessions (excluding lightdm)
+# TODO: make available for desktop manager, too!
+declare x_user="$(loginctl list-sessions --no-legend| sed -e 's/\s\{2,\}/ /g;s/^[[:space:]]*//' | \
+ cut -d ' ' -f 3| grep -v "lightdm"|uniq)"
+
+# Fail if there is no user set
+if [ -z "$x_user" ]; then
+ echo "error no user!"
+ exit 1
+fi
+
+# Export Xorg DISPLAY and XAUTHORITY
+# TODO: Get number of X DISPLAY from tmp
+#declare x_display="/tmp/.X11-unix/X*"
+export DISPLAY=:0
+export XAUTHORITY=/home/$x_user/.Xauthority
+
+# Define the log file
+declare log="/home/$x_user/.cache/$(basename $0)"
+if [[ ! -w "$log" ]]; then
+ touch "$log"
+ chown ${x_user}:${x_user} "$log"
+# exec > "$log" 2>&1
+fi
+
+declare -a arguments=( )
+declare -a connections=( )
+declare -a active_connections=( )
+declare -a available_connections=( )
+declare -a non_primary=( "eDP1" )
+declare -a pan=( "DP2-1" "eDP1" )
+declare -a pan_vertical=( 'empty' 'empty' ) # with empty placeholders!
+declare internal="eDP1"
+declare current_primary=""
+declare action=""
+
+# declare keywords (xrandr arguments)
+declare pre_output=" --output "
+declare post_auto=" --auto "
+declare post_primary=" --primary "
+declare post_pos_rightof=" --right-of"
+declare post_pos_leftof=" --left-of"
+declare post_off=" --off "
+
+function setup_xscreen()
+{
+ local outputs=( )
+ local connection_counter=0
+ case "$action" in
+ "open")
+ if [ ${#available_connections[@]} -gt 1 ]; then
+ for connection in ${pan[@]}
+ do
+ echo "$connection" >> $log
+ set +e
+ find_component_in "$connection" ${available_connections[@]}
+ if [ $? -eq 0 ]; then
+ echo "$connection is amongst the available outputs." >> $log
+ # adding --output argument
+ outputs=( ${outputs[@]:+${outputs[@]}} "$pre_output" )
+ # adding name of output
+ outputs=( ${outputs[@]:+${outputs[@]}} "$connection" )
+ # check whether output should not be primary in a multi output setup
+ find_component_in "$connection" ${non_primary[@]}
+ if [ $? -eq 0 ]; then
+ echo "$connection is setup for non-primary." >> $log
+ else
+ echo "$connection is NOT setup for non-primary." >> $log
+ # adding --primary argument
+ outputs=( ${outputs[@]:+${outputs[@]}} "$post_primary" )
+ fi
+ if [ $connection_counter -gt 0 ]; then
+ # adding a --right-of <connection before this one> argument
+ outputs=( ${outputs[@]:+${outputs[@]}} "$post_pos_rightof" "${pan[$((connection_counter-1))]}" )
+ fi
+ # adding --auto argument
+ outputs=( ${outputs[@]:+${outputs[@]}}"$post_auto" )
+ connection_counter=$(( $connection_counter + 1 ))
+ fi
+ set -e
+ done
+ fi
+ ;;
+ "close")
+ if [ ${#available_connections[@]} -gt 1 ]; then
+ for connection in ${pan[@]}
+ do
+ echo "$connection" >> $log
+ set +e
+ find_component_in "$connection" ${available_connections[@]}
+ if [ $? -eq 0 ]; then
+ echo "$connection is amongst the available outputs." >> $log
+ # adding --output argument
+ outputs=( ${outputs[@]:+${outputs[@]}} "$pre_output" )
+ # adding name of output
+ outputs=( ${outputs[@]:+${outputs[@]}} "$connection" )
+ # if the connection is not the internal output
+ if [ $connection != $internal ]; then
+ # check whether output should not be primary in a multi output setup
+ find_component_in "$connection" ${non_primary[@]}
+ if [ $? -eq 0 ]; then
+ echo "$connection is setup for non-primary." >> $log
+ else
+ echo "$connection is NOT setup for non-primary." >> $log
+ # adding --primary argument
+ outputs=( ${outputs[@]:+${outputs[@]}} "$post_primary" )
+ fi
+ if [ $connection_counter -gt 0 ]; then
+ # adding a --right-of <connection before this one> argument
+ outputs=( ${outputs[@]:+${outputs[@]}} "$post_pos_rightof" "${pan[$((connection_counter-1))]}" )
+ fi
+ # adding --auto argument
+ outputs=( ${outputs[@]:+${outputs[@]}}"$post_auto" )
+ connection_counter=$(( $connection_counter + 1 ))
+ else
+ # adding a --off argument for the interal screen
+ outputs=( ${outputs[@]:+${outputs[@]}} "$post_off" )
+ fi
+ fi
+ set -e
+ done
+ fi
+ ;;
+ esac
+echo "Calling: xrandr ${outputs[@]}" >> $log
+xrandr ${outputs[@]}
+}
+
+function find_component_in()
+{
+ local -r component=$1
+ shift
+ local value
+ for value in "$@"
+ do
+ [[ $value == "$component" ]] && return 0
+ done
+ return 1
+}
+
+function get_current_x_information()
+{
+ # get current xrandr settings
+ current_xrandr=$(xrandr)
+ # get current primary output from xrandr
+ current_primary=$(echo "$current_xrandr" | \
+ grep -wE '(\bconnected.*primary.*[0-9]{1,5}\x[0-9]{1,5}\+[0-9]{1,5}\+[0-9]{1,5})' | \
+ cut -d ' ' -f 1)
+ echo "Current primary output: $current_primary" >> $log
+ # get all current active connections
+ active_connections=( "${active_connections[@]:+${active_connections[@]}}" $(echo "$current_xrandr" | \
+ grep -wE '(\bconnected.*[0-9]{1,5}\x[0-9]{1,5}\+[0-9]{1,5}\+[0-9]{1,5})' | cut -d ' ' -f 1) )
+ echo "Current active connections: ${active_connections[@]}" >> $log
+ # get all currently available connections
+ available_connections=( "${available_connections[@]:+${available_connections[@]}}" $(echo "$current_xrandr" | \
+ grep -wE '(\bconnected.*)' | cut -d ' ' -f 1) )
+ echo "Currently available connections: ${available_connections[@]}" >> $log
+ # get all available connections
+ connections=( "${connections[@]:+${connections[@]}}" $(echo "$current_xrandr"| grep -v 'Screen' | cut -d ' ' -f 1))
+ echo "All current connections: ${connections[@]}" >> $log
+}
+
+function get_action()
+{
+ arguments=( "${arguments[@]:+${arguments[@]}}" "${@:+$@}" )
+# echo "${@:+$@}" >> $log
+# echo "${arguments[@]:+${arguments[@]}}" >> $log
+ if [ ${#arguments[@]} -gt 0 ];then
+ if [ "${arguments[0]}" = "button/lid" ]; then
+ case "${arguments[2]}" in
+ "open")
+ action="open"
+ ;;
+ "close")
+ action="close"
+ ;;
+ esac
+ elif [ "${arguments[0]}" = "login" ]; then
+ action="open"
+ fi
+ fi
+ echo "Action set: $action" >> $log
+}
+
+# pass arguments to the script to the get_action function
+get_action "${@:+$@}"
+get_current_x_information
+setup_xscreen
+