diff options
-rwxr-xr-x | bin/lid-switch-action | 260 |
1 files changed, 177 insertions, 83 deletions
diff --git a/bin/lid-switch-action b/bin/lid-switch-action index e4b45a7..a2779b7 100755 --- a/bin/lid-switch-action +++ b/bin/lid-switch-action @@ -5,100 +5,194 @@ # 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 -export DISPLAY=:0 -export XAUTHORITY=/home/dave/.Xauthority +set -e -u -# Check whether first parameter is a number -re='^[0-9]+$' -if ! [[ $1 =~ $re ]]; then - echo "error: Not a number" >&2; exit 1 -fi +# 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)" -# Define the log file -log_file="/home/dave/.log/lid-switch-action.log" -if [[ ! -w "$log_file" ]];then - touch "$log_file" - chown dave:users "$log_file" +# Fail if there is no user set +if [ -z "$x_user" ]; then + echo "error no user!" + exit 1 fi -echo "Calling lid-switch-action with $1" >> $log_file +# 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 -# Unsetting all possible connections -HDMI1=0 -HDMI2=0 -VGA1=0 -DP1=0 -DP2=0 +# 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 -# Store $1 as it will be overwritten soon -call=$1 +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="" -# while reading xrandr line by line, check its output -connections=0 -while read line -do - # if line contains connected but not disconnected, use it - if [[ "$line" == *connected* && "$line" != *disconnected* ]];then - xrandr_output[$connections]=$line - set -- ${xrandr_output[$connections]} - connected[$connections]=$1 - (( connections++ )) - fi -done < <(xrandr) +# 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 " -# Loop all connected displays -for i in ${connected[@]} -do - case $i in - "HDMI1") - HDMI1=1 - ;; - "HDMI2") - HDMI2=1 - ;; - "VGA1") - VGA1=1 - ;; - "DP1") - DP1=1 +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 ;; - "DP2") - DP2=1 + "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 -done +echo "Calling: xrandr ${outputs[@]}" >> $log +xrandr ${outputs[@]} +} -# Now checking which autorandr profile to use -case "$call" in - "0") - if [[ $connections -gt 1 ]];then # check if more than one connection - if [[ $HDMI1 -gt 0 ]];then - echo "HDMI1 connected." >> $log_file - /usr/bin/autorandr -l external-plugged & >> $log_file - elif [[ $DP2 -gt 0 ]];then - echo "DP2 connected." >> $log_file - /usr/bin/autorandr -l external-docked & >> $log_file - fi - else # else suspend - echo "Only one screen connected." >> $log_file - if [[ -f "/home/dave/.config/awesome/i3lock" ]];then - echo "Using i3lock to lock screen." >> $log_file - su dave -c "/home/dave/.config/awesome/i3lock" - fi - echo "Suspending." >> $log_file - systemctl suspend - fi - ;; - "1") - if [[ $connections -gt 1 ]];then # check if more than one connection - if [[ $HDMI1 -gt 0 ]];then - echo "HDMI1 connected." >> $log_file - /usr/bin/autorandr -l multi-plugged & >> $log_file - elif [[ $DP2 -gt 0 ]];then - echo "DP2 connected." >> $log_file - /usr/bin/autorandr -l multi-docked & >> $log_file - fi +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 - ;; -esac + fi + echo "Action set: $action" >> $log +} + +# pass arguments to the script to the get_action function +get_action "${@:+$@}" +get_current_x_information +setup_xscreen |