summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/chdt175
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 "${@}"