Skip to content

Instantly share code, notes, and snippets.

@AlexAtkinson
Last active July 13, 2023 15:31
Show Gist options
  • Save AlexAtkinson/01798b57296d077e1e7cd32f4192923c to your computer and use it in GitHub Desktop.
Save AlexAtkinson/01798b57296d077e1e7cd32f4192923c to your computer and use it in GitHub Desktop.
Automatic autorandr change

autorandr don't auto...

  1. Setup directories (Or use whatever you use for crons, but adjust these instructions accordingly)

    mkdir -p $HOME/crons/logs/
    mkdir $HOME/crons/autorandr
    
  2. Create script $HOME/crons/autorandr/autorandr-reloader.sh

    #!/usr/bin/env bash
    # autorandr-reloader.sh
    
    function logger2() {
      [[ $1 -eq 0 ]] && echo -e "$(date --utc +"%FT%T.%3NZ") - \e[01;30;41mEMERGENCY\e[0m: ${*:2}"
      [[ $1 -eq 1 ]] && echo -e "$(date --utc +"%FT%T.%3NZ") - \e[01;31;43mALERT\e[0m: ${*:2}"
      [[ $1 -eq 2 ]] && echo -e "$(date --utc +"%FT%T.%3NZ") - \e[01;97;41mCRITICAL\e[0m: ${*:2}"
      [[ $1 -eq 3 ]] && echo -e "$(date --utc +"%FT%T.%3NZ") - \e[01;31mERROR\e[0m: ${*:2}"
      [[ $1 -eq 4 ]] && echo -e "$(date --utc +"%FT%T.%3NZ") - \e[01;33mWARNING\e[0m: ${*:2}"
      [[ $1 -eq 5 ]] && echo -e "$(date --utc +"%FT%T.%3NZ") - \e[01;30;107mNOTICE\e[0m: ${*:2}"
      [[ $1 -eq 6 ]] && echo -e "$(date --utc +"%FT%T.%3NZ") - \e[01;39mINFO\e[0m: ${*:2}"
      [[ $1 -eq 7 ]] && echo -e "$(date --utc +"%FT%T.%3NZ") - \e[01;97;46mDEBUG\e[0m: ${*:2}"
      [[ $1 -eq 9 ]] && echo -e "$(date --utc +"%FT%T.%3NZ") - \e[01;32mSUCCESS\e[0m: ${*:2}"
    }
    
    function rc_handler() {
      if [[ $1 -eq $2 ]] ; then
        logger2 9 $task
      else
        logger2 3 $task - Exit Code: $2
      fi
    }
    function rc() {
      result=$?
      if [[ "$RC_LOG" == "true" ]]; then
        rc_handler "$1" "$result" | tee -a "$LOG_FILE"
      else
        rc_handler "$1" "$result"
      fi
    }
    function et() { echo -e "\n$task..."; }
    
    
    THIS_PID=$$
    function dupe_proc_check() {
      # Ensures this script isn't being run anywhere else on the system.
      PIDS=($(ps -ax -opid,cmd | awk -v this_script="${0##*/}" '$0 ~ this_script && ! /awk/ && ! /sh -c/ && /bash/ {print $1}' | head -n -1))
      for pid in ${PIDS[*]}; do
        if [[ $pid != $THIS_PID ]]; then
          logger2 2 Process is already running with PID $pid! Quitting.
          exit 1
        fi
      done
    }
    
    #trap 'rm -f $pidFile;' EXIT
    function lock_file_handler() {
      # Ensures this scirpt isn't run twice from the same place.
      if [[ $EUID -eq 0 ]]; then
        pidFile="/var/run/${0##*/}.pid.lock"
      else
        pidFile="$HOME/.${0##*/}.pid.lock"
      fi
      
      if [[ -f $pidFile ]]; then
        logger2 2 PID file detected!
        if ps -p $(cat $pidFile) &>/dev/null ; then
          if [[ ! $(ps -p $(cat $pidFile) -o cmd --no-headers) =~ "${0##*/}" ]]; then
            logger2 4 The process matching the pidFile \($(cat $pidFile)\) is NOT ${0##*/}!
            task="Deleting $pidFile"
      logger2 5 $task...
      rm -f $pidFile; rc 0
            logger2 6 Continuing...
          fi
          dupe_proc_check
        fi
      else
        #logger2 6 Creating pidfile $pidFile for pid $$.
        echo $$ > $pidFile
      fi
    }
    
    dupe_proc_check
    lock_file_handler
    
    state_file_a="$HOME/crons/autorandr/.connected.a.state"
    state_file_b="$HOME/crons/autorandr/.connected.b.state"
    
    export DISPLAY=$(w -h $USER | awk '$2 ~ /:[0-9.]*/{print $2}')
    [[ ! -f $state_file_a ]] && echo "$(xrandr -q | grep " connected" | cut -d ' ' -f1 | xargs)" > $state_file_a
    echo "$(xrandr -q | grep " connected" | cut -d ' ' -f1 | xargs)" > $state_file_b
    diff $state_file_a $state_file_b
    if [[ $(diff $state_file_a $state_file_b) ]]; then
      echo "$(xrandr -q | grep " connected" | cut -d ' ' -f1 | xargs)" > $state_file_a
      logger2 5 Configuration change detected! Running autorandr...
      autorandr --change --force
    fi
    if ! autorandr 2>&1 | grep -q "current"; then
      logger2 4 Autorandr config not applied! Retrying...
      autorandr --change --force
    fi
    
    rm -f $pidFile
    
  3. Make it executable

    chmod +x $HOME/crons/autorandr/reloader.sh
    
  4. Create the crontab entry (crontab -e)

    NOTE: This is how I get crons to run at a higher cadence than supported. Account for proc time if you do this.

    * * * * * /bin/bash -c 'for i in {1..29} ; do $HOME/crons/autorandr/autorandr-reloader.sh | tee -a $HOME/crons/logs/autorandr-reloader.log; sleep 2; done'
    
  5. Add this option to the top of /etc/rsyslog.conf to enable support for slashes in the programname.

    NOTE: This rsyslog work is only necessary if you want to silence the gdm-x-session spam in your syslog.

    global(parser.permitSlashInProgramName="on")
    

    REF: https://www.rsyslog.com/doc/v8-stable/configuration/properties.html

  6. Add this to the bottom of /etc/rsyslog.conf

    :programname, isequal, "/usr/libexec/gdm-x-session" ~
    
  7. Restart rsyslog

    systemctl restart syslog.socket rsyslog.service
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment