#!/bin/bash
set -e

OUTER_DISPLAY="${DISPLAY:-:50}"

# Real bug found and fixed here (2026-09-05): GNOME's own Settings ->
# Displays panel DOES correctly save a chosen resolution to
# ~/.config/monitors.xml (confirmed live -- a real <width>1024</width>/
# <height>768</height> entry was written after changing resolution) --
# but a fresh Xephyr always started sized to match the OUTER x2go
# window's *current* geometry, completely ignoring that saved file, so
# every login silently reverted to whatever size x2goclient's own
# session profile happened to be. Fixed by reading monitors.xml directly
# and starting Xephyr AT that saved size when one exists, rather than
# relying on Mutter's own RandR-restore timing against a Xephyr instance
# that was already forced to a different size before gnome-shell even
# started. Falls back to matching the outer nxagent display (the
# original behavior) when no saved preference exists yet -- change the
# session's Geometry in x2goclient's own preferences for that first-run
# default, same as before.
MONITORS_XML="$HOME/.config/monitors.xml"
GEOM=""
if [ -r "$MONITORS_XML" ]; then
	W=$(grep -m1 -o '<width>[0-9]*</width>' "$MONITORS_XML" | grep -o '[0-9]*')
	H=$(grep -m1 -o '<height>[0-9]*</height>' "$MONITORS_XML" | grep -o '[0-9]*')
	[ -n "$W" ] && [ -n "$H" ] && GEOM="${W}x${H}"
fi
if [ -z "$GEOM" ]; then
	GEOM=$(DISPLAY="$OUTER_DISPLAY" xdpyinfo 2>/dev/null | awk '/dimensions:/{print $2}')
fi
[ -z "$GEOM" ] && GEOM="1024x768"

# pick a free nested display number
N=150
while [ -e "/tmp/.X11-unix/X$N" ]; do
	N=$((N + 1))
done

DISPLAY="$OUTER_DISPLAY" /usr/bin/Xephyr ":$N" -screen "$GEOM" -noreset -resizeable >/tmp/xephyr-gnome-$N.log 2>&1 &
XEPHYR_PID=$!

# wait for the nested display to actually come up
for i in $(seq 1 100); do
	if DISPLAY=":$N" /usr/bin/xdpyinfo >/dev/null 2>&1; then
		break
	fi
	sleep 0.1
done

# make sure Xephyr gets cleaned up when gnome-session exits
trap "kill $XEPHYR_PID 2>/dev/null" EXIT

export DISPLAY=":$N"

# Real bug found and fixed here (2026-09-05): starting Xephyr at the
# saved size above is NOT enough -- confirmed live that gnome-shell's
# own monitor manager, on every fresh startup, ALWAYS auto-selects
# Xephyr's compiled-in maximum mode (1600x1200) regardless of what
# Xephyr actually started at, completely ignoring the -screen geometry.
# Worse, monitors.xml's own file-based restore can NEVER work around
# this with Xephyr specifically: Xephyr reports a literal 0Hz refresh
# rate for every mode it advertises, and Mutter's config validator
# rejects a stored rate of exactly 0 as syntactically invalid ("Monitor
# mode invalid") while ALSO rejecting any other rate for not matching a
# real advertised mode ("Invalid mode ... for monitor") -- there is no
# value that satisfies both checks, confirmed by testing both. Real,
# working fix: bypass GNOME's own broken restore path entirely and
# re-assert the saved resolution ourselves via a live `xrandr -s` once
# gnome-shell has actually started (a live RandR mode-set request isn't
# subject to the same monitors.xml rate validation at all) -- confirmed
# this genuinely sticks with Mutter already running, both via `xrandr`
# and visually. Runs in the background so it doesn't block gnome-session
# itself; only fires when GEOM came from a real saved preference, not
# the outer-display-derived first-run default (no point re-asserting
# what Xephyr already started at).
if [ -n "$W" ] && [ -n "$H" ]; then
	(
		for i in $(seq 1 100); do
			if pgrep -x gnome-shell >/dev/null 2>&1; then
				sleep 1
				xrandr -s "$GEOM" 2>/dev/null
				break
			fi
			sleep 0.2
		done
	) &
fi

/usr/bin/gnome-session "$@" &
GNOME_PID=$!
wait "$GNOME_PID"
