#!/bin/sh
# Generate kanshi's dock profile from kernel EDID.
#
# Neither identity kanshi can see is trustworthy here: Hyprland reports each
# monitor's serial on the other monitor's output, and connector names get
# renumbered when the dock brings displays back in a different order. The
# kernel reads EDID over each connector's own DDC channel and is correct, so
# connector names are resolved from serials fresh on every display change.

USER_NAME=connorjohnstone
CONF=/home/$USER_NAME/.config/kanshi/generated
SCALE=1.5

# Serials in the physical left-to-right order they sit on the desk.
ORDER="PB4HB16301805 PB4HB16301801"

exec 9>/run/monitor-layout.lock
flock -w 60 9 || exit 0

[ -n "$LAYOUT_DELAY" ] && sleep "$LAYOUT_DELAY"

connector_for_serial() {
	for c in /sys/class/drm/card*-*; do
		[ -r "$c/status" ] || continue
		[ "$(cat "$c/status")" = connected ] || continue
		if edid-decode <"$c/edid" 2>/dev/null | grep -qF "'$1'"; then
			echo "$c"
			return 0
		fi
	done
	return 1
}

# Same directory as $CONF so the final rename is atomic: kanshi reloads on
# SIGHUP and must never observe a half-written config.
tmp=$(mktemp "$CONF.XXXXXX") || exit 1
trap 'rm -f "$tmp"' EXIT INT TERM

body=""
x=0

for serial in $ORDER; do
	path=$(connector_for_serial "$serial") || continue
	name=$(basename "$path" | sed 's/^card[0-9]*-//')

	mode=$(head -1 "$path/modes" 2>/dev/null)
	[ -n "$mode" ] || continue
	width=$(awk -v m="${mode%%x*}" -v s="$SCALE" 'BEGIN{printf "%d", m / s}')

	body="$body	output $name enable position $x,0 scale $SCALE
"
	x=$((x + width))
done

if [ -n "$body" ]; then
	printf 'profile generated_dock {\n%s	output eDP-1 disable\n}\n' "$body" >"$tmp"
else
	: >"$tmp"
fi

chown "$USER_NAME:$USER_NAME" "$tmp"
chmod 0644 "$tmp"
mv -f "$tmp" "$CONF"

pkill -HUP -u "$USER_NAME" kanshi
