Files
hypr/scripts/multihead.zsh
2026-06-05 23:49:54 -04:00

114 lines
3.6 KiB
Bash
Executable File

#!/usr/bin/env zsh
#set -x
# Define your Monitor Serials (from your Kanshi config)
# Left Monitor: Ancor Communications Inc ASUS VS228 E3LMTF071438
SERIAL_LEFT="E3LMTF071438"
# Right Monitor: Ancor Communications Inc ASUS VS228 E3LMTF071391
SERIAL_RIGHT="E3LMTF071391"
### --- HELPER FUNCTIONS --- ###
# Function to find the current port name (e.g., DP-6, HDMI-A-1) for a given serial
get_monitor_port() {
local serial=$1
hyprctl monitors -j | jq -r --arg s "$serial" '.[] | select(.serial == $s) | .name'
}
# Wait for a specific monitor serial to appear in Hyprland
wait_for_monitor() {
local serial=$1
local max_retries=10 # Wait up to 5 seconds (10 * 0.5s)
local count=0
while [[ $count -lt $max_retries ]]; do
local port=$(get_monitor_port "$serial")
if [[ -n "$port" ]]; then
echo "$port"
return 0
fi
sleep 0.5
count=$(( count+1 ))
done
return 1
}
# Function to safely restart Waybar
restart_waybar() {
# Kill any running instances
pkill waybar
# Wait a moment for them to die
while pgrep -x waybar > /dev/null; do sleep 0.1; done
# Start fresh instance via uwsm in the background
uwsm app -- waybar &
}
### --- MAIN LOGIC --- ###
# Get current profile and arguments
old_profile="$(kanshictl status | awk -F': ' '{print $NF}')"
new_profile="${1}"
shift
# Check if profile actually changed (unless forced)
if [[ "${old_profile}" == "${new_profile}" ]]; then
if [[ "${1}" != "--force" ]] && [[ "${1}" != '-f' ]]; then
exit 0
fi
fi
# Path to your workspaces config
WS_CONFIG="${XDG_CONFIG_HOME}/hypr/workspaces.conf"
PAPER_CONFIG="${XDG_CONFIG_HOME}/hypr/hyprpaper.conf"
case "${new_profile}" in
home_office)
# 1. Dynamically find which port the monitors are currently plugged into
PORT_RIGHT=$(wait_for_monitor "$SERIAL_RIGHT")
PORT_LEFT=$(wait_for_monitor "$SERIAL_LEFT")
# Fallback: If for some reason we can't find them, default to eDP-1 to prevent crash
[[ -z "$PORT_LEFT" ]] && PORT_LEFT="eDP-1"
[[ -z "$PORT_RIGHT" ]] && PORT_RIGHT="eDP-1"
# 2. Assign Workspaces to the detected ports
# Right Monitor (Shell, Browser)
perl -pi -e "if (/defaultName:shell/) {s/monitor:.+?,/monitor:${PORT_RIGHT},/}" $WS_CONFIG
perl -pi -e "if (/defaultName:browser/) {s/monitor:.+?,/monitor:${PORT_RIGHT},/}" $WS_CONFIG
# Left Monitor (Work, Jobs)
perl -pi -e "if (/defaultName:work/) {s/monitor:.+?,/monitor:${PORT_LEFT},/}" $WS_CONFIG
perl -pi -e "if (/defaultName:jobs/) {s/monitor:.+?,/monitor:${PORT_LEFT},/}" $WS_CONFIG
# Laptop Screen (Meeting, Monitoring) - Explicitly assigning these ensures they don't get "stuck"
perl -pi -e "if (/defaultName:meeting/) {s/monitor:.+?,/monitor:eDP-1,/}" "$WS_CONFIG"
perl -pi -e "if (/defaultName:monitoring/) {s/monitor:.+?,/monitor:eDP-1,/}" "$WS_CONFIG"
# 3. Apply changes
kanshictl switch home_office
hyprctl reload
restart_waybar
;;
single_headed)
# Move EVERYTHING to the internal laptop screen
perl -pi -e 's/monitor:.*?,/monitor:eDP-1,/' "$WS_CONFIG"
kanshictl switch single_headed
hyprctl reload
restart_waybar
;;
fix_me)
# Treat "fix_me" (2 monitors) as single_headed temporarily
# This prevents the script from erroring out while waiting for the 3rd monitor
perl -pi -e 's/monitor:.*?,/monitor:eDP-1,/' "$WS_CONFIG"
kanshictl switch fix_me
hyprctl reload
restart_waybar
;;
*)
print "Invalid profile!" >&2
;;
esac
#set +x