Introduction
Aerospace is a tiling window manager for MacOS. One of its handy features is move-workspace-to-monitor --wrap-around next, which moves the current workspace to the next monitor and wraps around when reaching the last one.
This is an updated version of my previous article on replicating this behavior in Hyprland. Hyprland has since moved to a Lua-based configuration system, which changed the dispatch API. You can read more about the Lua migration on the Hyprland News page.
This guide (again, more like me dumping this script on the internet) shows the updated script.
Prerequisites
- Hyprland (with Lua config) - includes
hyprctlby default - jq - JSON processor used to parse
hyprctloutput
The Script
Add this script somewhere on your system, and make it executable.
#!/usr/bin/env bash
ACTIVE_WS_JSON=$(hyprctl activeworkspace -j)
WS_ID=$(echo "$ACTIVE_WS_JSON" | jq -r '.id')
CURRENT_MON=$(echo "$ACTIVE_WS_JSON" | jq -r '.monitor')
mapfile -t MONITORS < <(hyprctl monitors -j | jq -r '.[].name')
for i in "${!MONITORS[@]}"; do
if [[ "${MONITORS[$i]}" == "$CURRENT_MON" ]]; then
CURRENT_INDEX=$i
break
fi
done
NEXT_INDEX=$(( (CURRENT_INDEX + 1) % ${#MONITORS[@]} ))
NEXT_MON="${MONITORS[$NEXT_INDEX]}"
hyprctl dispatch "hl.dsp.workspace.move({ workspace = $WS_ID, monitor = \"$NEXT_MON\" })"How It Works
- Get active workspace info:
hyprctl activeworkspace -jreturns JSON with the current workspace ID and monitor name - Extract workspace ID and monitor:
jqparses the JSON to get.idand.monitor - Build monitor list:
hyprctl monitors -jreturns all connected monitors, which we store in an array - Find current monitor index: Loop through the array to find where the current monitor is positioned
- Calculate next monitor: Using modulo arithmetic
(current + 1) % totalgives us the next index, wrapping around to 0 when at the end - Move workspace:
hyprctl dispatch "hl.dsp.workspace.move(...)"uses the new Lua-style dispatch API to move the workspace to the target monitor
Keybinding
Then bind it to a keyboard shortcut in your Hyprland Lua config:
bind("ALT SHIFT TAB", function()
os.execute("<SCRIPT_FOLDER>/move_workspace_to_next_monitor.sh")
end)
-- now ALT + SHIFT + TAB will move your current workspace to the next screen.