From 3fcd32aa6d295ac62fe0e526931fc556a4060343 Mon Sep 17 00:00:00 2001 From: "B. Stack" Date: Thu, 13 Jul 2023 09:56:51 -0400 Subject: initial commit --- src/Makefile | 106 ++++++++++++++++++++++++ src/etc/sysconfig/fix-alttab | 14 ++++ src/etc/xdg/autostart/fix-alttab-daemon.desktop | 13 +++ src/usr/bin/fix-alttab-daemon | 43 ++++++++++ src/usr/libexec/fix-alttab | 75 +++++++++++++++++ src/usr/share/man/man1/fix-alttab-daemon.1.txt | 33 ++++++++ src/usr/share/man/man1/fix-alttab.1.txt | 33 ++++++++ 7 files changed, 317 insertions(+) create mode 100644 src/Makefile create mode 100644 src/etc/sysconfig/fix-alttab create mode 100644 src/etc/xdg/autostart/fix-alttab-daemon.desktop create mode 100755 src/usr/bin/fix-alttab-daemon create mode 100755 src/usr/libexec/fix-alttab create mode 100644 src/usr/share/man/man1/fix-alttab-daemon.1.txt create mode 100644 src/usr/share/man/man1/fix-alttab.1.txt (limited to 'src') diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..5e2d00f --- /dev/null +++ b/src/Makefile @@ -0,0 +1,106 @@ +# File: Makefile for fix-alttab +# Location: fix-alttab source package +# Author: bgstack15 +# Startdate: 2023-07-10-2 16:27 +# SPDX-License-Identifier: GPL-3.0 +# Title: Makefile for fix-alttab source package +# Project: fix-alttab +# Purpose: To use traditional Unix make utility +# History: +# Usage: +# Reference: +# outbound Makefile +# Improve: +# Document: +# Dependencies: +# build-devuan: bgscripts-core, txt2man + +APPNAME = fix-alttab +APPVERSION = 0.0.1 +SRCDIR = $(CURDIR) +prefix = /usr +SYSCONFDIR = $(DESTDIR)/etc +DEFAULTDIR = $(DESTDIR)/etc/sysconfig# for debian use '$(DESTDIR)/etc/default' +LIBEXECDIR = $(DESTDIR)$(prefix)/libexec +SHAREDIR = $(DESTDIR)$(prefix)/share +DOCDIR = $(SHAREDIR)/doc/$(APPNAME) +MANDIR = $(SHAREDIR)/man +BINDIR = $(DESTDIR)$(prefix)/bin + +# variables for deplist +DEPTYPE = dep +SEPARATOR = , + +awkbin :=$(shell which awk) +chmodbin :=$(shell which chmod) +cpbin :=$(shell which cp) +echobin :=$(shell which echo) +falsebin :=$(shell which false) +findbin :=$(shell which find) +grepbin :=$(shell which grep) +gzipbin :=$(shell which gzip) +installbin :=$(shell which install) +rmbin :=$(shell which rm) +rmdirbin :=$(shell which rmdir) +sedbin :=$(shell which sed) +sortbin :=$(shell which sort) +truebin :=$(shell which true) +uniqbin :=$(shell which uniq) +xargsbin :=$(shell which xargs) +txt2manwrapper :=/usr/bin/txt2man-wrapper + +with_man ?= YES + +all: build_man + -@#echo "Nothing to build." && ${truebin} + +ifeq ($(with_man),YES) +install: build_man install_files +else +install: install_files +endif + +.PHONY: clean install install_files build_man uninstall list deplist deplist_opts + +list: + @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | ${awkbin} -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | ${sortbin} | ${grepbin} -E -v -e '^[^[:alnum:]]' -e '^$@$$' + +deplist: + @# deplist 2020-04-18 input must be comma separated + @# DEPTYPE( dep , rec , sug ) for depends, recommends, or suggests + @if test -z "${DISTRO}" ; then ${echobin} "Please run \`make deplist\` with DISTRO= one of: `make deplist_opts 2>&1 1>/dev/null | ${xargsbin}`. Aborted." 1>&2 ; exit 1 ; fi + @if ! ${echobin} "${DEPTYPE}" | grep -qE "^(dep|rec|sug)$$" ; then ${echobin} "Please run \`make deplist\` with DEPTYPE= one of: dep, rec, sug. Undefined will use \`dep\`. Aborted." 1>&2 ; exit 1; fi + @${grepbin} -h --exclude-dir='doc' -riIE "\<${DEPTYPE}-" ${SRCDIR} | ${awkbin} -v "domain=${DISTRO}" -v "deptype=${DEPTYPE}" 'tolower($$2) ~ deptype"-"domain {$$1="";$$2="";print}' | tr ',' '\n' | ${sortbin} | ${uniqbin} | ${sedbin} -r -e 's/^\s*//' -e "s/\s*\$$/${SEPARATOR}/" | ${xargsbin} + +deplist_opts: + @# deplist_opts 2020-04-18 find all available dependency domains + @${grepbin} -h -o -riIE '\<(dep|rec|sug)-[^\ :]+:' ${SRCDIR} | ${sedbin} -r -e 's/(dep|rec|sug)-//;' -e 's/:$$//;' | ${sortbin} | ${uniqbin} 1>&2 + +install_files: + @ls usr/share/man/man*/*gz 1>/dev/null 2>&1 && echo "Including man pages." || : + @${echobin} Installing files to ${DESTDIR} + for td in $$( ${findbin} ${SRCDIR} -type d ! -name '.*.swp' ! -name 'Makefile' ! -name '.gitignore' ! -name 'README.md' -printf '%P\n' | ${sedbin} -r -e "s:etc/sysconfig:${DEFAULTDIR}:" -e "s:${DESTDIR}/?::" ) ; do ${installbin} -m0755 -d ${DESTDIR}/$${td} ; done + for tf in $$( ${findbin} ${SRCDIR} ! -type d ! -name '.*.swp' ! -name 'Makefile' ! -name '.gitignore' ! -name 'README.md' ! \( -path '*/man/*' -name '*.txt' \) ! -path '*/sysconfig/*' -printf '%P\n' ) ; do MODE=0644 ; echo "$${tf}" | grep -qE "(bin|libexec|deprecated)/" && MODE=0755 ; ${installbin} -m$${MODE} ${SRCDIR}/$${tf} ${DESTDIR}/$${tf} ; done + @# sysconfig/default dir + ${installbin} -m0644 -t ${DEFAULTDIR} ${SRCDIR}/etc/sysconfig/* + @# grab the project readme from above dir src/ + ${installbin} -m0644 -t ${DOCDIR} ${SRCDIR}/../README.md + +MAN_TXT:=$(wildcard usr/share/man/man*/*.txt) +MAN_GZ:= $(subst .txt,.gz,$(MAN_TXT)) + +build_man: $(MAN_GZ) + +$(MAN_GZ): %.gz: %.txt + ${txt2manwrapper} - < $< | ${gzipbin} > $@ + +uninstall: + @${echobin} SRCDIR=${SRCDIR} + ${rmbin} -f $$( ${findbin} ${SRCDIR} -mindepth 1 ! -type d -printf '%p\n' | ${sedbin} -r -e "s:/etc/sysconfig:${DEFAULTDIR}:" -e "s:^${SRCDIR}:${DESTDIR}:" -e "s:${DESTDIR}${DESTDIR}:${DESTDIR}:" ) + + # remove all installed directories that are now blank. + ${rmdirbin} ${DEFAULTDIR} 2>/dev/null || : ; for word in $$( ${findbin} ${SRCDIR} -mindepth 1 -type d -printf '%p\n' | ${sedbin} -r -e "s:^${SRCDIR}:${DESTDIR}:" | ${awkbin} '{ print length, $$0 }' | ${sortbin} -rn | ${awkbin} '{print $$2}' ) ; do ${findbin} $${word} -mindepth 1 1>/dev/null 2>&1 | read 1>/dev/null 2>&1 || { ${rmdirbin} "$${word}" 2>/dev/null || ${truebin} ; } ; done + +clean: + -@#${echobin} "target $@ not implemented yet! Gotta say unh." && ${falsebin} + -${rmbin} -f usr/share/man/man*/*.gz || : diff --git a/src/etc/sysconfig/fix-alttab b/src/etc/sysconfig/fix-alttab new file mode 100644 index 0000000..0b348c2 --- /dev/null +++ b/src/etc/sysconfig/fix-alttab @@ -0,0 +1,14 @@ +# Example fix-alttab.conf +# Usage: dot-sourced by fix-alttab and its daemon +# Locations: +# /etc/sysconfig/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 +FIX_ALTTAB_BIN=/usr/libexec/fix-alttab diff --git a/src/etc/xdg/autostart/fix-alttab-daemon.desktop b/src/etc/xdg/autostart/fix-alttab-daemon.desktop new file mode 100644 index 0000000..f02d8e6 --- /dev/null +++ b/src/etc/xdg/autostart/fix-alttab-daemon.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Categories=Utility;Accessibility; +Comment=forces alttab dialog to visible monitor +Exec=/usr/bin/fix-alttab-daemon +GenericName=Fix alttab daemon +Icon=system-run +Keywords=daemon;alttab; +Name=Fix-alttab daemon +StartupNotify=true +Terminal=false +Type=Application +Version=1.0 +Hidden=false diff --git a/src/usr/bin/fix-alttab-daemon b/src/usr/bin/fix-alttab-daemon new file mode 100755 index 0000000..f32084f --- /dev/null +++ b/src/usr/bin/fix-alttab-daemon @@ -0,0 +1,43 @@ +#!/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: +# dep-devuan: bgscripts-core +# Documentation: README.md + +# load settings +test -z "${DEFAULTSDIR}" && DEFAULTSDIR=/etc/sysconfig +grep -qiE 'de(vu|bi)an|ubuntu|mint' /etc/os-release 1>/dev/null 2>&1 && DEFAULTSDIR=/etc/default +test -f "${DEFAULTSDIR}/fix-alttab" && . "${DEFAULTSDIR}/fix-alttab" +test -f "${XDG_CONFIG_HOME:-~/.config}/fix-alttab" && . "${XDG_CONFIG_HOME:-~/.config}/fix-alttab" +test -z "${FIX_ALTTAB_BIN}" && FIX_ALTTAB_BIN=/usr/libexec/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_BIN}" )" + test "${_status}" != "${_laststatus}" && { + APPLY=1 "${FIX_ALTTAB_BIN}" | \ + { + if test "${_use_plecho}" = "1" ; + then + timeout 2 plecho + else + timeout 2 cat + fi + } + } | tee -a "${ALTTAB_DAEMON_LOGFILE:-fix-alttab-daemon.log}" + _laststatus="${_status}" +done diff --git a/src/usr/libexec/fix-alttab b/src/usr/libexec/fix-alttab new file mode 100755 index 0000000..c0b68b2 --- /dev/null +++ b/src/usr/libexec/fix-alttab @@ -0,0 +1,75 @@ +#!/bin/sh +# File: fix-alttab +# Location: /usr/libexec/fix-alttab +# Author: bgstack15 +# Startdate: 2023-07-10-2 08:10 +# SPDX-License-Identifier: GPL-3.0 +# 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: +# dep-devuan: xrandr, alttab +# Documentation: README.md + +# load settings +test -z "${DEFAULTSDIR}" && DEFAULTSDIR=/etc/sysconfig +grep -qiE 'de(vu|bi)an|ubuntu|mint' /etc/os-release 1>/dev/null 2>&1 && DEFAULTSDIR=/etc/default +test -f "${DEFAULTSDIR}/fix-alttab" && . "${DEFAULTSDIR}/fix-alttab" +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~/\&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 +} diff --git a/src/usr/share/man/man1/fix-alttab-daemon.1.txt b/src/usr/share/man/man1/fix-alttab-daemon.1.txt new file mode 100644 index 0000000..780f145 --- /dev/null +++ b/src/usr/share/man/man1/fix-alttab-daemon.1.txt @@ -0,0 +1,33 @@ +title fix-alttab-daemon +section 1 +project fix-alttab +volume General Commands Manual +date July 2023 +===== +NAME + fix-alttab-daemon - dynamically change where alttab displays based on available displays +SYNOPSIS + fix-alttab-daemon +OPTIONS + None +ENVIRONMENT + XDG_CONFIG_HOME is normally ~/.config, and determines where the per-user fix-alttab configuration file lives. +DESCRIPTION + This daemon loops over fix-alttab, an included script that performs the work of checking available monitors and then running alttab with various configs defined in the config file (normally ~/.config/fix-alttab or /etc/sysconfig/fix-alttab) + The point is to keep alttab within the viewable monitor area if I change inputs on one of my workstation monitors. +CONFIGURATION + These options are loaded from /etc/sysconfig/fix-alttab and then ~/.config/fix-alttab, so the last loaded value is used. + ALTTAB_DAEMON_LOOP how many seconds to sleep between each instance of checking the available displays. Default is 3. + ALTTAB_DAEMON_LOGFILE where to put logs. Default is "${XDG_RUNTIME_DIR}/fix-alttab-daemon.log" + ALTTAB_COMMON is the base command and any parameters to run. The first word of this value is the binary name that will be killalled if the alttab daemon needs to be restarted. Default is "alttab -w 1 -theme numix-circle" + The next four options are related to which monitors/X11 displays are available, and what options to pass to alttab when restarting it. + ALTTAB_LEFTYES_RIGHTYES "" + ALTTAB_LEFTNO_RIGHTYES "-vp 1920x1080+1920+0" which is the X11 geometry for this -vp options of alttab, which means that the maximum possible display screen for the alttab program is a 1920x1080-sized box, starting at pixel 1920,0, so my right monitor in a basic side-by-side organization. +AUTHOR + B. Stack +COPYRIGHT + GPL 3.0 +SEE ALSO + `fix-alttab(1)` +BUGS + Report any anomalies to the author. diff --git a/src/usr/share/man/man1/fix-alttab.1.txt b/src/usr/share/man/man1/fix-alttab.1.txt new file mode 100644 index 0000000..233a793 --- /dev/null +++ b/src/usr/share/man/man1/fix-alttab.1.txt @@ -0,0 +1,33 @@ +title fix-alttab +section 1 +project fix-alttab +volume General Commands Manual +date July 2023 +===== +NAME + fix-alttab - check active monitors and re-run alttab if different from before +SYNOPSIS + fix-alttab +OPTIONS + None +ENVIRONMENT + XDG_CONFIG_HOME is normally ~/.config, and determines where the per-user fix-alttab configuration file lives. + APPLY If 1, then actually re-run `alttab(1)` with the parameters in the config file. +DESCRIPTION + This is the main logic to react to current monitor status. that performs the work of checking available monitors and then running alttab with various configs defined in the config file (normally ~/.config/fix-alttab or /etc/sysconfig/fix-alttab) + The point is to keep alttab within the viewable monitor area if I change inputs on one of my workstation monitors. + Run this with `APPLY` unset, to print which monitors it detects. Then run with `APPLY=1` to re-run alttab. +CONFIGURATION + These options are loaded from /etc/sysconfig/fix-alttab and then ~/.config/fix-alttab, so the last loaded value is used. + ALTTAB_COMMON is the base command and any parameters to run. The first word of this value is the binary name that will be killalled if the alttab daemon needs to be restarted. Default is "alttab -w 1 -theme numix-circle" + The next four options are related to which monitors/X11 displays are available, and what options to pass to alttab when restarting it. + ALTTAB_LEFTYES_RIGHTYES "" + ALTTAB_LEFTNO_RIGHTYES "-vp 1920x1080+1920+0" which is the X11 geometry for this -vp options of alttab, which means that the maximum possible display screen for the alttab program is a 1920x1080-sized box, starting at pixel 1920,0, so my right monitor in a basic side-by-side organization. +AUTHOR + B. Stack +COPYRIGHT + GPL 3.0 +SEE ALSO + `fix-alttab-daemon(1)` +BUGS + Report any anomalies to the author. -- cgit