#!/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