Skip to content

Conversation

tamayotchi
Copy link

@tamayotchi tamayotchi commented Oct 8, 2025

Description

Adds a new feature to swap active workspaces across all monitors in a circular pattern.

  • New script: omarchy-swap-monitors for circular workspace rotation across all monitors
  • Includes proper error handling and user notifications
  • Validates monitor availability before attempting swap
2025-10-07.19-29-43.mp4

@woopstar
Copy link
Contributor

woopstar commented Oct 8, 2025

How does this work with a 3-monitor setup?

@rez1coder
Copy link
Contributor

How does this work with a 3-monitor setup?

This won't work because MONITORS[0] and MONITORS[1] are defined.

You'll need to add MONITORS[2] for the third monitor in the script. Similarly for 4+ monitors.

For a robust solution, dynamically detect monitors and iterate through them instead of hardcoding indices. No sane person uses more than 3 monitors anyway.

@woopstar
Copy link
Contributor

woopstar commented Oct 8, 2025

or a robust solution, dynamically detect monitors and iterate through them instead of hardcoding indices.

I know :) I was just too lazy to point it out. Wanted contributor to think of this instead 👯

Copy link
Contributor

@woopstar woopstar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this works:

#!/usr/bin/env bash
# Rotate workspaces across all monitors in Hyprland/Omarchy

readonly TMP_WORKSPACE=999
readonly APP_NAME="Omarchy"

mapfile -t MONITORS < <(hyprctl monitors -j | jq -r '.[].name')

if (( ${#MONITORS[@]} < 2 )); then
    notify-send "$APP_NAME" "Only one monitor detected — nothing to rotate."
    exit 0
fi

get_active_workspace() {
    hyprctl monitors -j | jq -r ".[] | select(.name==\"$1\") | .activeWorkspace.id"
}

# Store all active workspaces
declare -a WORKSPACES
for mon in "${MONITORS[@]}"; do
    ws=$(get_active_workspace "$mon")
    if [[ -z "$ws" ]]; then
        notify-send "$APP_NAME" "Could not detect workspace on $mon."
        exit 1
    fi
    WORKSPACES+=("$ws")
done

# Move current workspace to temp
hyprctl dispatch workspace "$TMP_WORKSPACE"
hyprctl dispatch moveworkspacetomonitor "$TMP_WORKSPACE" "${MONITORS[0]}"

# Rotate: each monitor gets the workspace from the previous monitor
for (( i=${#MONITORS[@]}-1; i>=0; i-- )); do
    prev_idx=$(( (i - 1 + ${#MONITORS[@]}) % ${#MONITORS[@]} ))
    hyprctl dispatch moveworkspacetomonitor "${WORKSPACES[$prev_idx]}" "${MONITORS[$i]}"
done

# Focus the workspace that moved to the first monitor
hyprctl dispatch workspace "${WORKSPACES[-1]}"

notify-send "$APP_NAME" "Rotated workspaces across ${#MONITORS[@]} monitors."

Copy link
Contributor

@woopstar woopstar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

omarchy-swap-monitors should go into the bin folder

Copy link
Contributor

@woopstar woopstar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested this last night. Works perfect on my 2 and 3 monitor setup.

# Ensure focus returns to the monitor the user was on.
dispatch focusmonitor "$ORIGINAL_MONITOR"

notify-send "$APP_NAME" "Rotated workspaces across ${#MONITORS[@]} monitors."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider to set timeouts on notifications

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants