Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Upcoming project: fix-alttab

This quick-and-dirty project is taking longer than I had hoped, and I have to get this post out! I am working on a little shell script daemon that will re-run alttab when I change inputs on one of my monitors, so alttab is always visible on the screen.

This is a preview of the fully-fleshed-out project (Makefile, xdg autostart entry, etc.). Here is file fix-alttab

#!/bin/sh
# File: fix-alttab
# Location: /usr/libexec/fix-alttab
# Author: bgstack15
# Startdate: 2023-07-10-2 08:10
# Title: fix-alttab
# History:
# Usage:
#    called by fix-alttab-daemon
# Reference:
#    https://unix.stackexchange.com/questions/537529/how-do-i-get-xdg-config-home-from-a-shell-script-command-line
# Improve:
# Dependencies:
#    xrandr, awk
# Documentation: README.md
# load settings
test -f /etc/bgscripts/fix-alttab.conf && . /etc/bgscripts/fix-alttab.conf
test -f "${XDG_CONFIG_HOME:-~/.config}/fix-alttab" && . "${XDG_CONFIG_HOME:-~/.config}/fix-alttab"
# just in case no settings defined there
test -z "${ALTTAB_COMMON}" && ALTTAB_COMMON="alttab -w 1 -theme numix-circle"
test -z "${ALTTAB_LEFTYES_RIGHTYES}" && ALTTAB_LEFTYES_RIGHTYES=""
test -z "${ALTTAB_LEFTNO_RIGHTYES}" && ALTTAB_LEFTNO_RIGHTYES="-vp 1920x1080+1920+0"
test -z "${ALTTAB_LEFTYES_RIGHTNO}" && ALTTAB_LEFTYES_RIGHTNO="" #unsupported
test -z "${ALTTAB_LEFTNO_RIGHTNO}" && ALTTAB_LEFTNO_RIGHTNO="" # unsupported
# for better security, strip out any semicolons from these values because we evaluate without quotes
_strip() {
   printf '%s' "${@}" | sed -r -e 's/;.*$//;'
}
ALTTAB_COMMON="$( _strip "${ALTTAB_COMMON}" )"
ALTTAB_LEFTYES_RIGHTYES="$( _strip "${ALTTAB_LEFTYES_RIGHTYES}" )"
ALTTAB_LEFTNO_RIGHTYES="$( _strip "${ALTTAB_LEFTNO_RIGHTYES}" )"
ALTTABLEFTYES_RIGHTNO="$( _strip "${ALTTABLEFTYES_RIGHTNO}" )"
ALTTAB_LEFTNO_RIGHTNO="$( _strip "${ALTTAB_LEFTNO_RIGHTNO}" )"
# always evaluate this
_ALTTAB_COMMAND_TO_KILL="$( echo "${ALTTAB_COMMON}" | awk '{print $1}' )"
# main
# set environment variables "left" and "right" to yes or no, to indicate if monitor is there.
unset right left
eval $( xrandr | awk 'BEGIN{a[0]="no";a[1]="yes"}/HDMI-1/{if($2~/\<connected/){r=1;}else{r=0};} /HDMI-0/{if($2~/\<connected/){l=1;}else{l=0;};} END{print "right="a[r];print "left="a[l];}' )
unset _ALTTAB_PARAMS
case "${left}${right}" in
   yesyes)
      printf '%s\n' "Using left yes, right yes"
      _ALTTAB_PARAMS="${ALTTAB_LEFTYES_RIGHTYES}"
      ;;
   noyes)
      printf '%s\n' "Using left no, right yes"
      _ALTTAB_PARAMS="${ALTTAB_LEFTNO_RIGHTYES}"
      ;;
   yesno)
      printf '%s\n' "Using left no, right yes"
      _ALTTAB_PARAMS="${ALTTAB_LEFTNO_RIGHTYES}"
      ;;
   nono)
      printf '%s\n' "Using left no, right no: UNSUPPORTED!"
      _ALTTAB_PARAMS="${ALTTAB_LEFTNO_RIGHTNO}"
      ;;
   *)
      printf '%s\n' "Unknown config: leftright \"${left}${right}\". Aborted." 1>&2 ; exit 1
      ;;
esac
test -n "${APPLY}" && {
   test -n "${DEBUG}" && set -x
   killall "${_ALTTAB_COMMAND_TO_KILL}"
   # unquoted here:
   ${ALTTAB_COMMON} ${_ALTTAB_PARAMS} &
   set +x
}

File fix-alttab-daemon which gets called by ~/.fluxbox/startup or with an entry in directory /etc/xdg/autostart/.

#!/bin/sh
# File: fix-alttab-daemon
# Location: /usr/bin
# Author: bgstack15
# Startdate: 2023-07-10-2 08:55
# SPDX-License-Identifier: GPL-3.0
# Title: fix-alttab-daemon
# Project: fix-alttab
# Purpose: Detect changes to connected HDMI monitors
# History:
# Usage:
#    run in ~/.fluxbox/startup in the background
# Reference:
# Improve:
# Dependencies:
#    plecho
#    fix-alttab
# Documentation: README.md
# load settings
test -f /etc/bgscripts/fix-alttab.conf && . /etc/bgscripts/fix-alttab.conf
test -f "${XDG_CONFIG_HOME:-~/.config}/fix-alttab" && . "${XDG_CONFIG_HOME:-~/.config}/fix-alttab"
command -v plecho 1>/dev/null && _use_plecho=1
unset _laststatus
while ! test -f /tmp/stop-fix-alttab-daemon ;
do
   sleep "${ALTTAB_DAEMON_LOOP:-3}"
   _status="$( APPLY= ./fix-alttab )"
   test "${_status}" != "${_laststatus}" && {
      APPLY=1 ./fix-alttab | \
      {
         test "${_use_plecho}" = "1" && timeout 2 plecho || cat
      }
   } | tee -a "${ALTTAB_DAEMON_LOGFILE:-fix-alttab-daemon.log}"
   _laststatus="${_status}"
done

And here is the config file. The above scripts read /etc/bgscripts/fix-alttab.conf first, and then ~/.config/fix-alttab.

# Example fix-alttab.conf
# Usage: dot-sourced by fix-alttab and its daemon
# Locations:
#    /etc/bgscripts/fix-alttab.conf
#    ~/.config/fix-alttab
ALTTAB_DAEMON_LOOP=3
ALTTAB_DAEMON_LOGFILE="${XDG_RUNTIME_DIR:~}/fix-alttab-daemon.log"
# First word here is the binary to run. This will be killalled if it needs to be run.
ALTTAB_COMMON="alttab -w 1 -theme numix-circle"
ALTTAB_LEFTYES_RIGHTYES=""
ALTTAB_LEFTNO_RIGHTYES="-vp 1920x1080+1920+0"
ALTTAB_LEFTYES_RIGHTNO="" # unsupported
ALTTAB_LEFTNO_RIGHTNO="" # unsupported

Yes, I'm in love with sleep loops. I aspire to be a Unix Master Foo.

Comments