dotfiles/.local/bin/sway-find-workspace

88 lines
2.5 KiB
Bash
Executable File

#!/usr/bin/env zsh
output_sets=()
# Get output ordering
for output in $(swaymsg -t get_outputs | jq '[ (.[] | select(.active) | pick(.name, .rect)) ] | sort_by(.rect.x) | .[] | .name' -r); do
output_sets+=$output
done
echo "Output sets: $output_sets" >&2
workspace_counts=()
total_workspaces=0
for output in {1..${#output_sets[@]}}; do
workspace_counts+=$(jq <~/.config/sway/workspaces.json ".contexts[.default_context] | [values[]][$((output - 1))] | length" -r)
((total_workspaces += workspace_counts[output]))
done
workspaces=$(swaymsg -t get_workspaces)
current_output=$(echo $workspaces | jq '.[] | select(.focused).output' -r)
current_workspace=$(echo $workspaces | jq '.[] | select(.focused).name' -r)
function get_previous_output_workspaces {
output=$1
previous_outputs=0
if ((output == 0)); then
echo 0
return
fi
for cur_output in {1..$output}; do
((previous_outputs += workspace_counts[cur_output]))
done
echo $previous_outputs
}
function get_ws {
ws_set=$1
ws_target=$2
echo "Searching for workspace $ws_target on output $ws_set" >&2
while ((ws_target > workspace_counts[ws_set + 1])); do
echo "Workspace $ws_target does not exist on output $ws_set, moving to the next one" >&2
((ws_set = (ws_set + 1) % ${#output_sets[@]}))
if [[ $ws_set == $1 ]]; then
echo "No more outputs to check, staying on the current workspace" >&2
echo $current_workspace
return
fi
done
workspace=$(($(get_previous_output_workspaces $ws_set) + ws_target))
echo "Looking at workspace $workspace (located on output $ws_target)" >&2
if [[ $workspace == $current_workspace ]]; then
echo "We're already on the target workspace, so we should look to change outputs" >&2
initial_ws_set=$ws_set
while :; do
ws_set=$(((ws_set + 1) % ${#output_sets[@]}))
echo "Checking output $ws_set" >&2
if ((ws_target <= workspace_counts[ws_set + 1])); then
workspace=$(($(get_previous_output_workspaces $ws_set) + ws_target))
break
elif ((ws_set == initial_ws_set)); then
# If we've looped around to the initial output, just stay on the current workspace
break
else
echo "Output $ws_set doesn't have enough workspaces (only ${workspace_counts[$((ws_set + 1))]}), moving to the next one" >&2
fi
done
fi
echo "Found on output $ws_set" >&2
echo $workspace
}
i=0
found=false
for output in $output_sets; do
if [[ $current_output == $output ]]; then
found=true
get_ws $i $1
fi
((i++))
done
if [[ $found == false ]]; then
echo "[ ERR ] Current output not found in list of outputs" >&2
fi