aboutsummaryrefslogtreecommitdiffstats
path: root/bin/lid-switch-action
blob: a2779b7e617cb9f4b4768806ff3ccadd486f61ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
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