diff options
-rwxr-xr-x | bin/chdt | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/bin/chdt b/bin/chdt new file mode 100755 index 0000000..3bd503a --- /dev/null +++ b/bin/chdt @@ -0,0 +1,175 @@ +#!/bin/sh + +set -eu + +ROWS=2 +COLS=6 +ORIENTATION='horizontal' + +debug=0 + +err() +{ + local fmt="${1}" + shift 1 + + printf "Error: ${fmt}\n" "${@}" 1>&2 + return 0 +} + +dbg() +{ + local fmt="${1}" + shift 1 + + case "${debug}" in '1') + printf "DEBUG: ${fmt}\n" "${@}" 1>&2 + esac + + return 0 +} + +get_desktop() +{ + local dt= + + dt=$(wmctrl -d | sed -n '/^[0-9][0-9]* *\* /{ s/ *\* .*$//; p; q; };') + case "${dt}" in + *[!0-9]*) + err 'Failed to get current desktop number' + return 1 + ;; + esac + + dbg 'Old desktop: %d' ${dt} + + printf '%d' ${dt} + return 0 +} + +inc_desktop() +{ + local dt=${1} + local dx=${2} + local dy=${3} + + case "${ORIENTATION}" in + [Hh]*) + x=$((${dt} % ${COLS})) + y=$((${dt} / ${COLS})) + dbg 'Old coordinates: (%d, %d)' ${x} ${y} + x=$(((${x} + ${COLS} + ${dx}) % ${COLS})) + y=$(((${y} + ${ROWS} + ${dy}) % ${ROWS})) + dbg 'New coordinates: (%d, %d)' ${x} ${y} + dt=$((${y} * ${COLS} + ${x})) + ;; + [Vv]*) + x=$((${dt} / ${ROWS})) + y=$((${dt} % ${ROWS})) + x=$(((${x} + ${dx}) % ${COLS})) + y=$(((${y} + ${dy}) % ${ROWS})) + dt=$((${x} * ${ROWS} + ${y})) + ;; + esac + + printf '%d' ${dt} + + return 0 +} + +set_desktop() +{ + local dt=${1} + shift 1 + + dbg 'New desktop: %d' ${dt} + + wmctrl -s ${dt} + + return 0 +} + +move_window() +{ + local dt=${1} + shift 1 + + dbg 'New desktop: %d' ${dt} + + wmctrl -r ':ACTIVE:' -t ${dt} + wmctrl -s ${dt} + + return 0 +} + +usage() +{ + printf 'Usage: %s [<options>] <direction>\n' "${0}" + printf '\n' + printf 'Where <direction> is any word beginning with (in any case):\n' + printf ' * "U" for up\n' + printf ' * "D" for down\n' + printf ' * "L" for left\n' + printf ' * "R" for right\n' + printf '\n' + printf 'Options:\n' + printf ' -w Move the active window\n' + printf ' -d Enable debugging output\n' + + return 0 +} + +main() +{ + local move_win= + local opt= + local dir= + local dx= + local dy= + local cur_dt= + local new_dt= + + move_win=0 + + while getopts 'wd' opt "${@}"; do + case "${opt}" in + 'w') move_win=1;; + 'd') debug=1;; + '?') + usage 1>&2 + return 1 + ;; + esac + done + shift $((${OPTIND} - 1)) + + if [ ${#} -ne 1 ]; then + usage 1>&2 + return 1 + fi + + dir="${1}" + shift 1 + + case "${dir}" in + [Uu]*) dx=0 dy=-1;; + [Dd]*) dx=0 dy=1 ;; + [Ll]*) dx=-1 dy=0 ;; + [Rr]*) dx=1 dy=0 ;; + *) + usage 1>&2 + return 1 + ;; + esac + + cur_dt=$(get_desktop) || return 1 + new_dt=$(inc_desktop ${cur_dt} ${dx} ${dy}) + case ${move_win} in + 1) move_window ${new_dt};; + 0) set_desktop ${new_dt};; + esac + + return 0 +} + +main "${@}" |