You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.7 KiB
123 lines
3.7 KiB
#!/usr/bin/env bash
|
|
|
|
if test "$BASH" = "" || "$BASH" -uc "a=();true \"\${a[@]}\"" 2>/dev/null; then
|
|
# Bash 4.4, Zsh
|
|
set -euo pipefail
|
|
else
|
|
# Bash 4.3 and older chokes on empty arrays with set -u.
|
|
set -eo pipefail
|
|
fi
|
|
shopt -s nullglob globstar
|
|
|
|
app_name=${1:-}
|
|
direction=${2:-next}
|
|
|
|
function echo_help {
|
|
echo "Usage: $0 window_class [direction]"
|
|
echo "Focuses one of the opened windows with the passed window_class on the condition of i3wm being currently running."
|
|
echo "If the window of such class is already focused, then another one will be focused, appropriate to the passed direction."
|
|
echo " window_class is a Window Manager window class"
|
|
echo " direction denotes which window should be focused; possible values are next or previous, next being the default."
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 Firefox"
|
|
echo " $0 Firefox previous"
|
|
echo " $0 Code previous"
|
|
}
|
|
|
|
if [ -z "$I3SOCK" ]
|
|
then
|
|
echo "i3wm is not running"
|
|
exit 127
|
|
fi
|
|
|
|
if [ "$app_name" = '-h' ] || [ "$app_name" = '--help' ]
|
|
then
|
|
echo_help
|
|
exit 0
|
|
fi
|
|
|
|
# Check if the app name was passed and if not show an error to the user
|
|
if [ -z "$app_name" ]
|
|
then
|
|
echo "You need to pass an app name as the first param!"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if the direction is a valid argument
|
|
if [ "$direction" != 'next' ] && [ "$direction" != 'previous' ]
|
|
then
|
|
echo "Invalid direction passed! Expected 'next' or 'previous'."
|
|
exit 2
|
|
fi
|
|
|
|
# Check if i3-msg is installed also silencing all of the output
|
|
if ! command -v i3-msg >/dev/null
|
|
then
|
|
echo "i3-msg is needed for this script to work!"
|
|
exit 3
|
|
fi
|
|
|
|
# Check if jq is installed also silencing all of the output
|
|
if ! command -v jq >/dev/null
|
|
then
|
|
echo "jq is needed for this script to work!"
|
|
exit 3
|
|
fi
|
|
|
|
# Get all the opened windows
|
|
all_windows=$(i3-msg -t get_tree | jq ".nodes | map(.nodes[]) | map(.nodes[]) | map(recurse(.nodes[]))[] | select(.window_properties != null)")
|
|
# Get all of the windows that belong to the $app_name
|
|
app_windows=$(echo "$all_windows" | jq "select(.window_properties.class == \"$app_name\")")
|
|
|
|
# Check if any windows were found and exit if not.
|
|
if [ -z "$app_windows" ]
|
|
then
|
|
echo "No windows for said app found"
|
|
exit 4
|
|
fi
|
|
|
|
# From now on I drop the app_ prefix in the variable naming schema, since variables will refer to
|
|
# app windows only.
|
|
mapfile -t windows_ids < <(echo "$app_windows" | jq '.id')
|
|
windows_count=${#windows_ids[@]}
|
|
windows_count=$(((windows_count - 1)))
|
|
|
|
focused_window_id=$(echo "$app_windows" | jq "select(.focused == true) | .id")
|
|
if [ -n "$focused_window_id" ]
|
|
then
|
|
# The app is already focused, so we need to focus its next/previous instance
|
|
for focused_index in "${!windows_ids[@]}"
|
|
do
|
|
# Current ID is that of the focused window, just break to save the index and go on.
|
|
if [ "$focused_window_id" = "${windows_ids[$focused_index]}" ]
|
|
then
|
|
break;
|
|
fi
|
|
done
|
|
else
|
|
# The app is not focused yet, so we need to do some hackery! Since we do some calculations and
|
|
# bounds checking below, -1 is appropriate here.
|
|
# If the user wants the next window, then the first one is appropriate.
|
|
# If they want a previous one, then the last one will be used.
|
|
focused_index=-1
|
|
fi
|
|
|
|
if [ "$direction" = "next" ]
|
|
then
|
|
new_focused_index=$(((focused_index + 1)))
|
|
else
|
|
new_focused_index=$(((focused_index - 1)))
|
|
fi
|
|
|
|
if [ "$new_focused_index" -gt "$windows_count" ]
|
|
then
|
|
# The calculated index is bigger than the windows count, so wrap around, wrap around my child!
|
|
new_focused_index=0
|
|
elif [ "$new_focused_index" -lt 0 ]
|
|
then
|
|
# Same as above, but this time wrap around backwards.
|
|
new_focused_index=$windows_count
|
|
fi
|
|
|
|
i3-msg "[con_id=\"${windows_ids[$new_focused_index]}\"] focus"
|
|
|