Skip to content

Instantly share code, notes, and snippets.

@fbrinker
Last active March 6, 2024 11:09
Show Gist options
  • Save fbrinker/df9cfbc84511d807f45041737ff3ea02 to your computer and use it in GitHub Desktop.
Save fbrinker/df9cfbc84511d807f45041737ff3ea02 to your computer and use it in GitHub Desktop.
Swap i3 displays / workspaces between displays
#!/usr/bin/env bash
# requires jq
DISPLAY_CONFIG=($(i3-msg -t get_outputs | jq -r '.[]|"\(.name):\(.current_workspace)"'))
for ROW in "${DISPLAY_CONFIG[@]}"
do
IFS=':'
read -ra CONFIG <<< "${ROW}"
if [ "${CONFIG[0]}" != "null" ] && [ "${CONFIG[1]}" != "null" ]; then
echo "moving ${CONFIG[1]} right..."
i3-msg -- workspace --no-auto-back-and-forth "${CONFIG[1]}"
i3-msg -- move workspace to output right
fi
done
@olorton
Copy link

olorton commented Mar 6, 2024

I have taken a stab at re-writing this based on all the examples above. The behaviour I expect is:

  • Works with two displays, not more
  • Swap the currently active workspaces on each display
  • Maintain focus on the display that had focus before the swap
#!/usr/bin/env bash

if ! command -v jq &>/dev/null; then
    echo "jq could not be found"
    exit 1
fi

# Swaps workspaces between two displays, focus stays on the current active display

DISPLAY_CONFIG="$(i3-msg -t get_outputs | jq -r '.[]|select(.active == true) |"\(.current_workspace)"')"
ACTIVE_DISPLAY="$(i3-msg -t get_workspaces | jq -r '.[]|select(.focused == true) | "\(.output)"')"
IFS=$'\n'
for ROW in ${DISPLAY_CONFIG}; do
    i3-msg -- workspace --no-auto-back-and-forth "$ROW"
    i3-msg -- move workspace to output next
done
sleep 0.15
i3-msg -- focus output "${ACTIVE_DISPLAY}"

Notable changes I've made:

  • The bash globbing was causing all sorts of problems with workspace names that had spaces in them. So I've removed that in favour of string splitting on new lines.
  • Fixed the move workspace command to use the next token which works with horizontally and vertically arranged monitors.
  • I do not like having a sleep in there, but the final msg is useless without it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment