diff --git a/README.md b/README.md index dfd9979..0e6e78f 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ through all of the application's windows. Options: -f -- force COMMAND to launch if process found but no windows found -n -- do not fork into background when launching COMMAND + -r -- cycle through windows in reverse order -p -- always launch COMMAND when ARGs passed (see Argument Passthrough in man page) -c NAME -- find window using NAME as WM_CLASS (instead of COMMAND) diff --git a/jumpapp b/jumpapp index 32e55e7..f272da4 100755 --- a/jumpapp +++ b/jumpapp @@ -10,6 +10,7 @@ Otherwise, launch COMMAND (with opitonal ARGs) to start the application. Options: -f -- force COMMAND to launch if process found but no windows found -n -- do not fork into background when launching COMMAND + -r -- cycle through windows in reverse order -p -- always launch COMMAND when ARGs passed (see Argument Passthrough in man page) -c NAME -- find window using NAME as WM_CLASS (instead of COMMAND) @@ -17,8 +18,8 @@ Options: } main() { - local classid cmdid force fork=1 passthrough= - while getopts c:fhi:np opt; do + local classid cmdid force fork=1 passthrough='' in_reverse='' + while getopts c:fhi:npr opt; do case "$opt" in c) classid="$OPTARG" ;; f) force=1 ;; @@ -26,6 +27,7 @@ main() { i) cmdid="$OPTARG" ;; n) fork='' ;; p) passthrough=1; force=1 ;; # passthrough implies force + r) in_reverse=1 ;; esac done @@ -41,9 +43,7 @@ main() { shift check_for_prerequisites && - - classid="$classid" cmd="$cmd" cmdid="$cmdid" force="$force" fork="$fork" passthrough="$passthrough" \ - jumpapp "$@" + jumpapp "$@" } check_for_prerequisites() { @@ -65,7 +65,7 @@ jumpapp() { local windowids=( $(list_matching_windowids "$classid" "${pids[@]}") ) if (( ${#windowids[@]} )) && ! needs_passthrough "$@"; then - activate_window "$(get_next_window "${windowids[@]}")" || + activate_window "$(get_subsequent_window "${windowids[@]}")" || die "Error: unable to focus window for '$cmdid'" else if (( ${#pids[@]} )) && [[ -z "$force" ]]; then @@ -125,6 +125,30 @@ select_normal_windows() { done } +get_subsequent_window() { + if [[ -n "$in_reverse" ]]; then + get_prev_window "$@" + else + get_next_window "$@" + fi +} + +get_prev_window() { + local active=$(get_active_windowid) prev + + if (( $1 == active )); then + shift $(( $# - 1 )) + printf '%s\n' "$1" + else + while [[ "$1" ]] && (( $1 != active )); do + prev=$1 + shift + done + + printf '%s\n' "$prev" + fi +} + get_next_window() { local first=$1 diff --git a/t/test_jumpapp b/t/test_jumpapp index 3b58e7f..749b013 100755 --- a/t/test_jumpapp +++ b/t/test_jumpapp @@ -142,6 +142,28 @@ it_calls_activate_window_with_first_windowid_when_last_is_active() { assertEquals 456 "$activate_window_arg" } +it_calls_activate_window_with_last_windowid_when_first_is_active_and_r_flag_is_passed() { + active_windowid=456 + list_windows_output='456 somehost 123 -1 someapp + 567 somehost 123 -1 someapp + 678 somehost 123 -1 someapp' + main -r someapp + + assertNotNull 'activate_window() called' "$activate_window_called" + assertEquals 678 "$activate_window_arg" +} + +it_calls_activate_window_with_first_windowid_when_second_is_active_and_r_flag_is_passed() { + active_windowid=567 + list_windows_output='456 somehost 123 -1 someapp + 567 somehost 123 -1 someapp + 678 somehost 123 -1 someapp' + main -r someapp + + assertNotNull 'activate_window() called' "$activate_window_called" + assertEquals 456 "$activate_window_arg" +} + it_throws_an_error_when_process_is_running_but_window_type_is_not_normal() { list_pids_for_command_output='123' list_windows_output='456 somehost 123 -1 someapp'