diff options
Diffstat (limited to 'bin/lid-switch-action')
-rwxr-xr-x | bin/lid-switch-action | 198 |
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 + |