diff --git a/dotfiles/config/hypr/hyprland.conf b/dotfiles/config/hypr/hyprland.conf index 0fc94550..bb865cb8 100644 --- a/dotfiles/config/hypr/hyprland.conf +++ b/dotfiles/config/hypr/hyprland.conf @@ -454,6 +454,9 @@ bind = $mainMod CTRL, 0, workspace, 10 # Workspace cycling (like XMonad's cycleWorkspaceOnCurrentScreen) bind = $mainMod, backslash, exec, ~/.config/hypr/scripts/workspace-back.sh +# Swap current workspace with another (like XMonad's swapWithCurrent) +bind = $hyper, 5, exec, ~/.config/hypr/scripts/swap-workspaces.sh + # Go to next empty workspace (like XMonad's moveTo Next emptyWS) bind = $hyper, E, workspace, empty diff --git a/dotfiles/config/hypr/scripts/swap-workspaces.sh b/dotfiles/config/hypr/scripts/swap-workspaces.sh new file mode 100755 index 00000000..cc044817 --- /dev/null +++ b/dotfiles/config/hypr/scripts/swap-workspaces.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# Swap the contents of the current workspace with another workspace. +# Intended to mirror XMonad's swapWithCurrent behavior. + +set -euo pipefail + +CURRENT_WS="$(hyprctl activeworkspace -j | jq -r '.id')" +if [[ -z "${CURRENT_WS}" || "${CURRENT_WS}" == "null" ]]; then + exit 0 +fi + +TARGET_WS="${1:-}" + +if [[ -z "${TARGET_WS}" ]]; then + WS_LIST="$({ + seq 1 10 + hyprctl workspaces -j | jq -r '.[].id' 2>/dev/null || true + } | awk 'NF {print $1}' | awk '!seen[$0]++' | sort -n)" + + TARGET_WS="$(printf "%s\n" "${WS_LIST}" | rofi -dmenu -p "Swap with workspace")" +fi + +if [[ -z "${TARGET_WS}" || "${TARGET_WS}" == "null" ]]; then + exit 0 +fi + +if [[ "${TARGET_WS}" == "${CURRENT_WS}" ]]; then + exit 0 +fi + +if ! [[ "${TARGET_WS}" =~ ^-?[0-9]+$ ]]; then + notify-send "Swap Workspace" "Invalid workspace: ${TARGET_WS}" + exit 1 +fi + +WINDOWS_CURRENT="$(hyprctl clients -j | jq -r --arg ws "${CURRENT_WS}" '.[] | select((.workspace.id|tostring) == $ws) | .address')" +WINDOWS_TARGET="$(hyprctl clients -j | jq -r --arg ws "${TARGET_WS}" '.[] | select((.workspace.id|tostring) == $ws) | .address')" + +for ADDR in ${WINDOWS_CURRENT}; do + hyprctl dispatch movetoworkspace "${TARGET_WS},address:${ADDR}" +done + +for ADDR in ${WINDOWS_TARGET}; do + hyprctl dispatch movetoworkspace "${CURRENT_WS},address:${ADDR}" +done