88 lines
2.5 KiB
Bash
Executable File
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
|