1 #!/bin/bash
   2 
   3 active=0
   4 windows=()
   5 
   6 workspace=$(wmctrl -d | awk '/\*/ { print $NF }')
   7 selector=".num == $workspace"
   8 
   9 [[ $1 == -a || $1 == --all ]] &&
  10 shift && selector='.focused != null'
  11 
  12 while read _ act _ id; do
  13     [[ $act == true ]] && active=$id
  14     [[ $id != null ]] && windows+=($id)
  15 done < <(
  16     i3-msg -t get_tree |
  17     jq ".nodes[].nodes[].nodes[] | select($selector)" |
  18     sed '/"window"\|"focused"/!d; /^   /!d; y/,/ /' | paste - -
  19 )
  20 
  21 prev=${windows[-1]}
  22 next=${windows[0]}
  23 
  24 for window in ${windows[@]}; do
  25     [[ $found ]] && next=$window && break
  26     (( $window != $active )) && prev=$window
  27     (( $window == $active )) && found=1
  28 done
  29 
  30 case $1 in
  31     prev) i3-msg [id=$prev] focus;;
  32     next) i3-msg [id=$next] focus;;
  33 
  34    first) i3-msg [id=${windows[0]}] focus;;
  35     last) i3-msg [id=${windows[-1]}] focus;;
  36 
  37     *) i3-msg [id=${windows[$1]}] focus;;
  38 esac