#!/usr/bin/env bash # Rotate the CURRENTLY FOCUSED monitor in 90° steps: 0→90→180→270→0… set -euo pipefail notify() { if command -v notify-send >/dev/null 2>&1; then notify-send -a "Hyprland" "$1" "${2:-}" else [ -n "${2:-}" ] && printf '%s: %s\n' "$1" "$2" >&2 || printf '%s\n' "$1" >&2 fi } # Read monitors MON_JSON="$(hyprctl -j monitors 2>/dev/null || true)" if [ -z "$MON_JSON" ]; then notify "Hyprland error" "Couldn’t read monitors via hyprctl." exit 1 fi # Focused monitor info if command -v jq >/dev/null 2>&1; then NAME="$(printf '%s' "$MON_JSON" | jq -r '.[] | select(.focused==true) | .name' | head -n1)" DESC="$(printf '%s' "$MON_JSON" | jq -r '.[] | select(.focused==true) | .description' | head -n1)" TFORM="$(printf '%s' "$MON_JSON" | jq -r '.[] | select(.focused==true) | (.transform // 0)' | head -n1)" else NAME=""; DESC=""; TFORM=""; FOC=0; GOT=0 while IFS= read -r line || [ -n "$line" ]; do if [[ $line =~ ^Monitor[[:space:]]+([^[:space:]]+)[[:space:]]+\(ID[[:space:]] ]]; then if (( FOC==1 )); then GOT=1; break; fi NAME="${BASH_REMATCH[1]}"; DESC=""; TFORM=""; FOC=0 elif [[ $line =~ ^[[:space:]]*description:[[:space:]]*(.*)$ ]]; then DESC="${BASH_REMATCH[1]}" elif [[ $line =~ ^[[:space:]]*transform:[[:space:]]*([0-9]+)$ ]]; then TFORM="${BASHREMATCH[1]}" elif [[ $line =~ ^[[:space:]]*focused:[[:space:]]*yes$ ]]; then FOC=1 elif [[ -z $line ]]; then if (( FOC==1 )); then GOT=1; break; fi fi done < <(hyprctl monitors 2>/dev/null) if (( GOT==0 && FOC==1 )); then GOT=1; fi if (( GOT==0 )); then NAME=""; fi : "${TFORM:=0}" fi if [ -z "${NAME:-}" ] || [ "${NAME:-null}" = "null" ]; then notify "No active monitor to rotate" "Couldn’t determine a focused monitor." exit 1 fi # Use description if available (most specific), else connector name if [ -n "${DESC:-}" ] && [ "${DESC:-null}" != "null" ]; then IDENT="desc:${DESC}" else IDENT="${NAME}" # bare connector name; no "name:" prefix fi # Base monitor string BASE="${IDENT}, highres@highrr, auto-right, 1" # Compute next transform in 90° steps (ignore flipped bit if present) if ! [[ "${TFORM:-}" =~ ^[0-9]+$ ]]; then TFORM=0; fi BASE_ROT=$(( TFORM % 4 )) NEXT=$(( (BASE_ROT + 1) % 4 )) DEG=$(( NEXT * 90 )) run_hyprctl() { if ! OUT="$(hyprctl keyword monitor "$1" 2>&1)"; then notify "hyprctl failed" "$OUT" exit 1 fi } run_hyprctl "$BASE, transform, $NEXT" notify "Rotation applied" "${DESC:-$NAME} → ${DEG}° (transform $NEXT)"