Files
dotfiles/.config/hypr/scripts/monitor-toggle.sh

133 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Quick display control for Hyprland
# Profiles:
# laptop -> keep eDP-2, disable all externals
# dual -> eDP-2 + primary external
# triple -> eDP-2 + both externals
# Toggles:
# toggle-externals -> if any external enabled => laptop; else => triple (or dual if only one preset)
# dpms-toggle-focused -> blank/unblank the currently focused monitor (does NOT change layout)
set -euo pipefail
PRIMARY="eDP-2"
# --- exact enable lines (copy from hyprland.conf) ---
EXT1='desc:Samsung Electric Company S24F350 H4ZR302705, highres@highrr, auto-right, 1'
EXT2='desc:Samsung Electric Company S24F350 H4ZK111233, highres@highrr, auto-right, 1, transform, 1'
# Optional fallback by connector (harmless if not present)
EXT_FALLBACK='HDMI-A-1, highres@highrr, auto-right, 1'
# Which external is the "main" one you prefer for Dual:
DUAL_MAIN="$EXT1"
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
}
hypr() {
local out
if ! out="$(hyprctl "$@" 2>&1)"; then
notify "hyprctl failed" "$out"
exit 1
fi
}
jqok(){ command -v jq >/dev/null; }
monjson(){ hyprctl -j monitors 2>/dev/null || true; }
any_external_enabled() {
if jqok; then
monjson | jq -e --arg P "$PRIMARY" '.[] | select(.name!=$P and (.disabled!=true))' >/dev/null
else
hyprctl monitors | awk -v P="$PRIMARY" '/^Monitor /{gsub(/^Monitor[ \t]+/, "", $0); split($0,a," "); if (a[1]!=P){print; exit 0}}' | grep -q .
fi
}
disable_all_externals() {
if jqok; then
mapfile -t names < <(monjson | jq -r --arg P "$PRIMARY" '.[] | select(.name!=$P) | .name')
else
mapfile -t names < <(hyprctl monitors | awk -v P="$PRIMARY" '/^Monitor /{gsub(/^Monitor[ \t]+/, "", $0); split($0,a," "); if (a[1]!=P) print a[1]}')
fi
for n in "${names[@]:-}"; do
hypr keyword monitor "$n, disable"
done
}
enable_line() {
local line="$1"
[ -n "$line" ] && hypr keyword monitor "$line"
}
profile_laptop() {
disable_all_externals
notify "Profile: Laptop-only" "$PRIMARY active, externals disabled"
}
profile_dual() {
# Ensure only one external is on
disable_all_externals
enable_line "$DUAL_MAIN"
notify "Profile: Dual" "Enabled main external with preferred transform"
}
profile_triple() {
# Ensure both externals are on (and only those two)
disable_all_externals
enable_line "$EXT1"
enable_line "$EXT2"
# You can drop EXT_FALLBACK if you don't actually need it:
# enable_line "$EXT_FALLBACK"
notify "Profile: Triple" "Enabled both externals"
}
toggle_externals() {
if any_external_enabled; then
profile_laptop
else
# Prefer triple if we have two presets, else dual
if [ -n "$EXT1" ] && [ -n "$EXT2" ]; then
profile_triple
else
profile_dual
fi
fi
}
dpms_toggle_focused() {
# Blank/unblank the currently focused output, layout unchanged
local name
if jqok; then
name="$(monjson | jq -r '.[] | select(.focused==true) | .name // empty')"
else
name="$(hyprctl monitors | awk '$1=="Monitor"{gsub(/^Monitor[ \t]+/,""); split($0,a," "); name=a[1]} /focused: yes/{print name; exit}')"
fi
[ -z "$name" ] && { notify "No focused monitor" ""; exit 2; }
hypr dispatch dpms toggle "$name"
notify "DPMS toggle" "$name"
}
case "${1:-}" in
laptop) profile_laptop ;;
dual) profile_dual ;;
triple) profile_triple ;;
toggle-externals) toggle_externals ;;
dpms-toggle-focused) dpms_toggle_focused ;;
*)
cat <<EOF
Usage:
$(basename "$0") laptop # eDP-2 only
$(basename "$0") dual # eDP-2 + main external
$(basename "$0") triple # eDP-2 + both externals
$(basename "$0") toggle-externals # flip between laptop-only and (dual/triple)
$(basename "$0") dpms-toggle-focused # blank/unblank focused output (no layout change)
EOF
exit 2
;;
esac