#!/bin/sh
# DPHMS payload v40 (machine-id symlink fix): machine-id dbus fix; theme as files. Every look setting (panel, wallpaper, GTK/icon/cursor theme, window
# theme, terminal colours) is now written as XFCE config XML BEFORE any XFCE process starts
# (container-dphms-theme), so it no longer depends on D-Bus/xfconfd being healthy. The live xfconf
# writes below are now only a best-effort refresh. The GTK theme name is case-correct (WhiteSur-Dark).
# DPHMS payload v26: v25 + D-Bus service activation restored + DPHMS branding/dock.
# v26 ROOT CAUSE (from the v25 phone screenshots): the custom session-bus config lacked
# <standard_session_servicedirs/>, so xfconfd / Thunar's FileManager service / notifications
# could never be D-Bus-activated. Every xfconf write failed (no DPHMS theme, no panel
# config, no branding) and desktop icons died with 'Launch Error'. Fixed in dbus-session.conf;
# this script also starts xfconfd itself as a belt-and-braces measure and launches the dock.
# v25: v23 + SVG-icon fix. Session manager is OPTIONAL.
# v24: GTK renders SVG icons through glycin, which wraps its loader in bwrap
# --unshare-all. proot has no user namespaces, so every icon load failed
# ("Loader process exited early with status 1") and took xfce4-session,
# xfdesktop and xfce4-terminal down with it. Two layers: (a) glycin's own
# documented switch, (b) a bwrap shim first on PATH for glycin builds that
# ignore the switch. Both live only inside this container session.
# Order: (1) wait for bus, (2) try xfce4-session, (3) if no window manager
# appears, start xfwm4 + panel + desktop directly with NO session manager and
# NO dbus dependency, (4) always leave a visible terminal, (5) keep alive.
export DISPLAY=:1 HOME=/root USER=root XDG_CURRENT_DESKTOP=XFCE
export XDG_RUNTIME_DIR=/tmp/xdg-runtime
export GDK_BACKEND=x11 LIBGL_ALWAYS_SOFTWARE=1 NO_AT_BRIDGE=1 XFWM4_NO_COMPOSITING=1
unset SESSION_MANAGER WAYLAND_DISPLAY
export GLYCIN_DISABLE_SANDBOX=i-know-the-risks
[ -x /usr/local/share/dphms/shim/bwrap ] && export PATH=/usr/local/share/dphms/shim:$PATH
# sockets that proot refuses to bind on the filesystem: keep agents off
unset SSH_AUTH_SOCK GPG_AGENT_INFO
export GNOME_KEYRING_CONTROL=/dev/null
mkdir -p "$XDG_RUNTIME_DIR" /root/.vnc; chmod 700 "$XDG_RUNTIME_DIR"
L=/root/.vnc/session.log
echo "[*] Session v40 start (glycin sandbox off, bwrap shim ${PATH%%:*}): DISPLAY=$DISPLAY bus=${DBUS_SESSION_BUS_ADDRESS:-none}"
i=0; until xprop -root >/dev/null 2>&1 || [ $i -ge 10 ]; do sleep 1; i=$((i+1)); done
xprop -root >/dev/null 2>&1 && echo "[*] X server reachable" || echo "[!] X server NOT reachable on $DISPLAY"
if [ -n "$DBUS_SESSION_BUS_ADDRESS" ] && command -v dbus-send >/dev/null 2>&1; then
  timeout 6 dbus-send --session --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames >/dev/null 2>&1 \
    && echo "[*] D-Bus handshake OK" || echo "[!] D-Bus handshake failed"
fi
# v27: write the whole DPHMS look as config files first (no D-Bus needed), THEN start XFCE.
echo "[*] DPHMS theme (file-based):"
if [ -x /usr/local/bin/dphms-theme ]; then sh /usr/local/bin/dphms-theme 2>&1 | tee -a "$L"; else echo "  FAIL dphms-theme missing"; fi
# v26: make sure xfconfd (the settings daemon) is actually serving before ANY xfconf write.
XFCONFD=$(ls /usr/lib/xfce4/xfconf/xfconfd /usr/lib/xfconf/xfconfd /usr/lib/aarch64-linux-gnu/xfce4/xfconf/xfconfd 2>/dev/null | head -1)
if ! timeout 4 xfconf-query -c xsettings -l >/dev/null 2>&1; then
  if [ -n "$XFCONFD" ]; then
    echo "[*] xfconfd not answering via D-Bus activation - starting it directly ($XFCONFD)"
    ("$XFCONFD" >> "$L" 2>&1 &)
  else
    echo "[!] xfconfd binary not found"
  fi
  j=0; until timeout 3 xfconf-query -c xsettings -l >/dev/null 2>&1 || [ $j -ge 8 ]; do sleep 1; j=$((j+1)); done
fi
timeout 4 xfconf-query -c xsettings -l >/dev/null 2>&1 && echo "[*] xfconfd OK (settings writes will work)" || echo "[!] xfconfd still unreachable - theme will not apply"
# solid DPHMS background so a working X is obvious
xsetroot -solid "#1E1E1E" 2>/dev/null
timeout 5 xfconf-query -c xfwm4 -p /general/use_compositing -s false -n -t bool 2>/dev/null
# (2) full session, first choice
xfce4-session >> "$L" 2>&1 &
SPID=$!; echo "$SPID" > /root/.vnc/session.pid
sleep 10
# (3) direct components if the session manager produced no window manager
if ! pgrep -x xfwm4 >/dev/null 2>&1; then
  echo "[!] No window manager after 10s — starting XFCE components directly (no session manager)."
  (xfwm4 --compositor=off --sm-client-disable >> "$L" 2>&1 &)
  sleep 2
fi
pgrep -x xfwm4 >/dev/null 2>&1 || { echo "[!] xfwm4 failed — trying openbox/twm fallback."; (command -v openbox >/dev/null 2>&1 && openbox >> "$L" 2>&1 &) || (twm >> "$L" 2>&1 &); }
# v27: xfsettingsd applies xsettings.xml (GTK theme, icons, cursor, font) to running apps. xfce4-session
# normally starts it; without a session it never ran, so the theme files were ignored.
pgrep -x xfsettingsd >/dev/null 2>&1 || (command -v xfsettingsd >/dev/null 2>&1 && xfsettingsd --sm-client-disable >> "$L" 2>&1 &)
sleep 1
pgrep -x xfce4-panel >/dev/null 2>&1 || (xfce4-panel --sm-client-disable >> "$L" 2>&1 &)
pgrep -x xfdesktop  >/dev/null 2>&1 || (xfdesktop --sm-client-disable >> "$L" 2>&1 &)
sleep 4
# v24: a second pass — xfdesktop/panel often need the icon loader to settle first
pgrep -x xfdesktop  >/dev/null 2>&1 || { echo "[!] xfdesktop still down — retrying."; (xfdesktop --disable-wm-check >> "$L" 2>&1 &); sleep 2; }
pgrep -x xfce4-panel >/dev/null 2>&1 || { echo "[!] xfce4-panel still down — retrying."; (xfce4-panel --disable-wm-check >> "$L" 2>&1 &); sleep 2; }
# v24b THEME PASS: the wallpaper/theme/panel settings were only ever written by
# .xinitrc (which this session script never runs) and by stage-3 at install time
# when no bus exists, so every xfconf write failed and xfdesktop had no image to
# draw (= flat grey with a moving cursor). Apply them NOW, with the bus live,
# and log each step so the console shows exactly what worked.
xq() { timeout 6 xfconf-query "$@" >> "$L" 2>&1 && echo "  ok   xfconf $*" || echo "  FAIL xfconf $*"; }
echo "[*] Theme pass (bus=${DBUS_SESSION_BUS_ADDRESS:-none}):"
WALL=/usr/share/backgrounds/dphms/dphms-dark-1280x720.png
[ -f "$WALL" ] || WALL=$(ls /usr/share/backgrounds/WhiteSur*/*.jpg /usr/share/backgrounds/WhiteSur*/*.png 2>/dev/null | head -1)
echo "  wallpaper file: ${WALL:-NONE} ($( [ -f "$WALL" ] && echo exists || echo MISSING ))"
if [ -n "$WALL" ] && [ -f "$WALL" ]; then
  for mon in monitor0 monitorVNC-0; do
    xq -c xfce4-desktop -p /backdrop/screen0/$mon/workspace0/last-image -n -t string -s "$WALL"
    xq -c xfce4-desktop -p /backdrop/screen0/$mon/workspace0/image-style -n -t int -s 3
  done
  timeout 5 xfdesktop --reload >> "$L" 2>&1 || true
fi
ICON=""; for t in WhiteSur-dark WhiteSur Papirus-Dark Adwaita hicolor; do [ -d /usr/share/icons/$t ] && ICON=$t && break; done
[ -n "$ICON" ] && xq -c xsettings -p /Net/IconThemeName -n -t string -s "$ICON" || echo "  skip  icon theme (none installed)"
CURN=WhiteSur-cursors; [ -d /usr/share/icons/DPHMS-Finger/cursors ] && CURN=DPHMS-Finger
xq -c xsettings -p /Gtk/CursorThemeName -n -t string -s "$CURN"
xq -c xsettings -p /Gtk/CursorThemeSize -n -t int -s 48
printf 'Xcursor.theme: %s\nXcursor.size: 48\n' "$CURN" > /root/.Xresources
xrdb -merge /root/.Xresources >> "$L" 2>&1 || true
xsetroot -cursor_name left_ptr >> "$L" 2>&1 || true
echo "  cursor    : $CURN (48px)"
# v26 DPHMS BRANDING: xfwm4 titlebar theme, red accent, dark GTK, panel look
xq -c xfwm4 -p /general/theme -n -t string -s "$( [ -d /usr/share/themes/DPHMS-Dark/xfwm4 ] && echo DPHMS-Dark || echo WhiteSur-dark )"
xq -c xsettings -p /Gtk/FontName -n -t string -s "Sans 10"
xq -c xfwm4 -p /general/title_font -n -t string -s "Sans Bold 10"
xq -c xfwm4 -p /general/button_layout -n -t string -s "CMH|T"
# top panel: slim, dark, DPHMS grey background, full width
# v27: panel config is written as a file by dphms-theme; only rebuild if that file is missing
if [ ! -s /root/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml ]; then
  echo "  panel xml missing - letting XFCE build its default layout"
  pkill -x xfce4-panel 2>/dev/null; sleep 1
  (xfce4-panel --disable-wm-check >> "$L" 2>&1 &); sleep 3
fi
# v26: already-installed phones never rerun stage 2, so top up missing dock pieces here (time-boxed,
# never blocks the desktop, logs the outcome). Needs data/Wi-Fi; offline it just reports and moves on.
MISS=""
command -v plank >/dev/null 2>&1 || MISS="$MISS plank"
command -v dconf >/dev/null 2>&1 || MISS="$MISS dconf"
if [ -n "$MISS" ]; then
  echo "[*] Missing packages:$MISS - trying pacman (30s limit)"
  (timeout 60 pacman -S --noconfirm --needed $MISS >> "$L" 2>&1 && echo "  ok   installed$MISS" || echo "  FAIL could not install$MISS (offline? dock will be skipped)") &
  w=0; while [ $w -lt 30 ] && [ -n "$(jobs -p 2>/dev/null)" ]; do sleep 1; w=$((w+1)); done
fi
# v28: user-level Firefox launcher that goes through the sandbox-off wrapper (the system one calls
# /usr/lib/firefox/firefox directly, which crashes every tab under proot)
mkdir -p /root/.local/share/applications
printf '[Desktop Entry]\nVersion=1.0\nType=Application\nName=Firefox\nComment=Web Browser\nExec=/usr/local/bin/firefox %%u\nIcon=firefox\nTerminal=false\nCategories=Network;WebBrowser;\nMimeType=text/html;x-scheme-handler/http;x-scheme-handler/https;\n' > /root/.local/share/applications/firefox.desktop
# v26 DOCK: the v25 autostart ran `plank --preferences -t Dphms` (opens the prefs window, -t is not a
# theme flag) and a setup entry that DELETED every launcher. Plank also reads dock1/launchers, not
# docklets/launchers. Build the dock here, deterministically, then launch it.
if command -v plank >/dev/null 2>&1; then
  D=/root/.config/plank/dock1; mkdir -p "$D/launchers" /root/.local/share/plank/themes/Dphms
  rm -f "$D"/launchers/*.dockitem
  n=0
  for app in /root/.local/share/applications/dphms.desktop /root/.local/share/applications/dphms-store.desktop /root/.local/share/applications/dphms-slots.desktop /root/.local/share/applications/firefox.desktop /usr/share/applications/xfce4-terminal.desktop /usr/share/applications/thunar.desktop /usr/share/applications/xfce4-settings-manager.desktop; do
    [ -f "$app" ] || continue
    printf '[PlankDockItemPreferences]\nLauncher=file://%s\n' "$app" > "$D/launchers/$(basename "$app" .desktop).dockitem"; n=$((n+1))
  done
  [ -f /root/.config/plank/theme/dphms/dock.theme ] && cp /root/.config/plank/theme/dphms/dock.theme /root/.local/share/plank/themes/Dphms/dock.theme
  echo "[*] Dock: $n launchers, theme Dphms"
  # Plank keeps its preferences in dconf (not a text file). dconf writes need a reachable session bus,
  # which the v26 service-dir fix provides. If dconf is missing or the write fails, the log line says so
  # and the dock still starts with Plank's default theme.
  if command -v dconf >/dev/null 2>&1; then
    K=/net/launchpad/plank/docks/dock1
    dconf write $K/theme "'Dphms'" >> "$L" 2>&1 && echo "  ok   dock theme Dphms" || echo "  FAIL dock theme (dconf)"
    dconf write $K/position "'bottom'" >> "$L" 2>&1
    dconf write $K/icon-size 48 >> "$L" 2>&1
    dconf write $K/zoom-enabled true >> "$L" 2>&1
    dconf write $K/zoom-percent 150 >> "$L" 2>&1
    dconf write $K/hide-mode "'none'" >> "$L" 2>&1
    dconf write $K/dock-items "[$(ls "$D/launchers" | sed "s/.*/'&'/" | paste -sd, -)]" >> "$L" 2>&1
  else
    echo "  FAIL dconf missing - dock uses default theme"
  fi
  pgrep -x plank >/dev/null 2>&1 || (plank >> "$L" 2>&1 &)
  sleep 3
  pgrep -x plank >/dev/null 2>&1 && echo "  dock plank is running" || echo "  FAIL dock plank did not start (see session.log)"
else
  echo "[!] plank not installed - no dock"
fi
# (4) guaranteed visible window
pgrep -x xfce4-terminal >/dev/null 2>&1 || (xfce4-terminal --disable-server --title='DPHMS Terminal' >> "$L" 2>&1 &)
pgrep -x xfce4-terminal >/dev/null 2>&1 || (xterm -title 'DPHMS Terminal' -bg '#121212' -fg '#FF2A2A' >> "$L" 2>&1 &)
# v32: Thunar goes through the local-files-only wrapper (default file manager, dock item)
sed -i 's#^Launcher=file:///usr/bin/thunar.*#Launcher=file:///usr/share/applications/thunar.desktop#' /root/.config/plank/dock1/launchers/thunar.dockitem 2>/dev/null

# ============================================================================================
# v38 THUNAR HANG-PROOFING (Richard: "still having thunar problems").
# ROOT CAUSE: the wrapper (/usr/local/bin/thunar) is only used when something resolves `thunar` through
# PATH. Since v26 restored D-Bus service activation, anything that asks to "open a folder" (desktop
# Home / File System icons, Open Containing Folder, xdg-open of a directory) activates
#   org.xfce.FileManager / org.xfce.Thunar / org.freedesktop.FileManager1
# whose service files hard-code `Exec=/usr/bin/thunar --daemon`. That bypasses the wrapper, so Thunar
# starts WITH gvfs/udisks/tumbler reachable and in daemon mode: it maps its window ("root - Thunar") but
# never paints it (the blank box in the screenshot, with stale desktop pixels showing through).
# FIX, three layers so no launch path can reach the real binary un-wrapped:
#  (1) per-user D-Bus service files that point every Thunar activation name at the wrapper
#      (~/.local/share/dbus-1/services wins over /usr/share/dbus-1/services),
#  (2) per-user .desktop entries that override the system ones (Exec=wrapper), incl. folder MIME default,
#  (3) mask the helper daemons Thunar waits on, so a stray activation can never start them.
# ============================================================================================
WRAP=/usr/local/bin/thunar
SVC=/root/.local/share/dbus-1/services; mkdir -p "$SVC"
for N in org.xfce.FileManager org.xfce.Thunar org.freedesktop.FileManager1; do
  printf '[D-BUS Service]\nName=%s\nExec=%s\n' "$N" "$WRAP" > "$SVC/$N.service"
done
# the xfce FileManager service is only ever asked to open a folder/window, never to run as a daemon
printf '[D-BUS Service]\nName=org.xfce.FileManager\nExec=%s\n' "$WRAP" > "$SVC/org.xfce.FileManager.service"
# (3) mask gvfs/tumbler/udisks/polkit activation: an empty per-user service file for a name wins, and
# `false` makes the activation fail fast instead of hanging Thunar for the 25s D-Bus timeout
for N in org.gtk.vfs.Daemon org.gtk.vfs.Metadata org.gtk.vfs.UDisks2VolumeMonitor org.gtk.vfs.GoaVolumeMonitor \
         org.gtk.vfs.MTPVolumeMonitor org.gtk.vfs.GPhoto2VolumeMonitor org.gtk.vfs.AfcVolumeMonitor \
         org.freedesktop.thumbnails.Thumbnailer1 org.freedesktop.UDisks2 org.freedesktop.PolicyKit1; do
  printf '[D-BUS Service]\nName=%s\nExec=/bin/false\n' "$N" > "$SVC/$N.service"
done
# (2) desktop entries: Exec goes through the wrapper, folders open with it, NO thunar-volman autostart
APPS=/root/.local/share/applications; mkdir -p "$APPS"
cat > "$APPS/thunar.desktop" <<'T'
[Desktop Entry]
Version=1.0
Type=Application
Name=File Manager
GenericName=File Manager
Comment=Browse the filesystem
Icon=org.xfce.thunar
Exec=/usr/local/bin/thunar %U
Terminal=false
StartupNotify=false
Categories=System;Utility;Core;GTK;FileManager;
MimeType=inode/directory;
T
cat > "$APPS/thunar-bulk-rename.desktop" <<'T'
[Desktop Entry]
Type=Application
Name=Bulk Rename
Exec=/usr/bin/thunar --bulk-rename %F
NoDisplay=true
T
# "V4L2 video capture utility" in the screenshot's window menu is the thunar-volman / v4l auto-action entry
# list leaking into the title-bar menu; there is no camera here, so hide those entries entirely.
for f in thunar-settings thunar-volman-settings; do
  printf '[Desktop Entry]\nType=Application\nName=%s\nNoDisplay=true\nHidden=true\n' "$f" > "$APPS/$f.desktop"
done
mkdir -p /root/.config/autostart
for f in thunar thunar-volman xfce4-thunar-volman gvfs-udisks2-volume-monitor gvfs-goa-volume-monitor gvfs-mtp-volume-monitor gvfs-gphoto2-volume-monitor gvfs-afc-volume-monitor tumblerd; do
  printf '[Desktop Entry]\nType=Application\nName=%s\nHidden=true\nX-GNOME-Autostart-enabled=false\n' "$f" > "/root/.config/autostart/$f.desktop"
done
# folders open with the wrapper, in every mimeapps source
if ! grep -q 'inode/directory' /root/.config/mimeapps.list 2>/dev/null; then
  sed -i 's#^\[Default Applications\]#[Default Applications]\ninode/directory=thunar.desktop#' /root/.config/mimeapps.list 2>/dev/null
fi
# refresh the desktop database so the overrides are picked up immediately (needs no bus)
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$APPS" >> "$L" 2>&1
# any Thunar left over from a previous run is the broken kind (daemon / unwrapped): drop it now
for p in $(pgrep -x thunar 2>/dev/null); do kill "$p" 2>/dev/null; done
pkill -x gvfsd 2>/dev/null; pkill -x tumblerd 2>/dev/null; pkill -x thunar-volman 2>/dev/null
echo "[*] Thunar hang-proofing: dbus services -> wrapper, desktop entries -> wrapper, gvfs/tumbler/udisks masked"
# self-check: prove the wrapper is what a D-Bus request would run
[ -x "$WRAP" ] && echo "  ok   wrapper $WRAP" || echo "  FAIL wrapper missing"
grep -q "usr/local/bin/thunar" "$SVC/org.xfce.FileManager.service" && echo "  ok   org.xfce.FileManager -> wrapper" || echo "  FAIL FileManager service"

# v31: no more "Untrusted application launcher" boxes: mark every desktop launcher trusted.
for f in /root/Desktop/*.desktop /root/.local/share/applications/dphms*.desktop; do
  [ -f "$f" ] || continue
  chmod +x "$f" 2>/dev/null
  gio set "$f" metadata::trusted true >> "$L" 2>&1 || gio set -t string "$f" metadata::xfce-exe-checksum "$(sha256sum "$f" | cut -d' ' -f1)" >> "$L" 2>&1
done
echo "  launchers trusted: $(ls /root/Desktop/*.desktop 2>/dev/null | wc -l)"
# v31: no more "Choose Preferred Application / Mail Reader" box: Firefox handles mailto: and web links
mkdir -p /root/.config/xfce4 /root/.config/xfce4/xfconf/xfce-perchannel-xml
# v34: register real XFCE helper entries (category X-XFCE-MailReader / X-XFCE-WebBrowser) and point helpers.rc at them
mkdir -p /root/.local/share/xfce4/helpers /root/.local/share/applications
cat > /root/.local/share/xfce4/helpers/dphms-mail.desktop <<'H'
[Desktop Entry]
Version=1.0
Icon=mail-message-new
Type=X-XFCE-Helper
StartupNotify=false
Name=DPHMS Mail (opens in Firefox)
X-XFCE-Binaries=firefox;
X-XFCE-Category=MailReader
X-XFCE-Commands=%B;
X-XFCE-CommandsWithParameter=%B "mailto:%s";
H
cat > /root/.local/share/xfce4/helpers/dphms-browser.desktop <<'H'
[Desktop Entry]
Version=1.0
Icon=web-browser
Type=X-XFCE-Helper
StartupNotify=false
Name=DPHMS Browser (Firefox)
X-XFCE-Binaries=firefox;
X-XFCE-Category=WebBrowser
X-XFCE-Commands=%B;
X-XFCE-CommandsWithParameter=%B "%s";
H
printf 'FileManager=Thunar\nWebBrowser=dphms-browser\nMailReader=dphms-mail\nTerminalEmulator=xfce4-terminal\n' > /root/.config/xfce4/helpers.rc
xdg-mime default firefox.desktop x-scheme-handler/mailto x-scheme-handler/http x-scheme-handler/https text/html >> "$L" 2>&1 || true
# v36: mimeapps.list as a FILE too (xfce4-mime-helper and Firefox both read it; some
# builds ignore xdg-mime when the bus is half-up). Firefox is the default carrier for
# web links AND mailto: — no "Choose Preferred Application" boxes, ever.
mkdir -p /root/.local/share/applications
cat > /root/.config/mimeapps.list <<'M'
[Default Applications]
x-scheme-handler/http=firefox.desktop
x-scheme-handler/https=firefox.desktop
x-scheme-handler/mailto=firefox.desktop
text/html=firefox.desktop
application/x-extension-htm=firefox.desktop
application/x-extension-html=firefox.desktop
x-scheme-handler/about=firefox.desktop
x-scheme-handler/unknown=firefox.desktop
[Added Associations]
x-scheme-handler/http=firefox.desktop
x-scheme-handler/https=firefox.desktop
x-scheme-handler/mailto=firefox.desktop
M
# v36: default CURSOR for every toolkit: env vars beat config files for Xvnc+GTK4
export XCURSOR_THEME="$CURN" XCURSOR_SIZE=48
printf 'Xcursor.theme: %s\nXcursor.size: 48\n' "$CURN" > /root/.Xresources
# v34: software rendering with the compositor off never clears stale pixels, so repaint the whole screen once everything is up
( sleep 6; timeout 5 xfdesktop --reload >> "$L" 2>&1 || true; command -v xrefresh >/dev/null 2>&1 && xrefresh >> "$L" 2>&1 ) &
# v29 SPLASH -> DESKTOP: panel, dock and terminal are up, so replace the boot screen with the real wallpaper.
REAL=$(cat /root/.vnc/wallpaper 2>/dev/null)
XD=/root/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml
if [ -n "$REAL" ] && [ -s "$XD" ] && grep -q 'dphms-splash' "$XD"; then
  sed -i "s#/usr/share/backgrounds/dphms/dphms-splash-[0-9x]*\.png#$REAL#g" "$XD"
  for m in monitor0 monitorVNC-0 monitorVNC-1 monitorscreen; do
    timeout 3 xfconf-query -c xfce4-desktop -p /backdrop/screen0/$m/workspace0/last-image -s "$REAL" 2>/dev/null
  done
  timeout 6 xfdesktop --reload >> "$L" 2>&1 || { pkill -x xfdesktop 2>/dev/null; sleep 1; (xfdesktop --disable-wm-check >> "$L" 2>&1 &); }
  echo "  splash -> desktop wallpaper: $REAL"
fi
echo "[*] DPHMS theme check:"
X=/root/.config/xfce4/xfconf/xfce-perchannel-xml
for f in xsettings xfwm4 xfce4-desktop xfce4-panel; do [ -s "$X/$f.xml" ] && echo "  ok   $f.xml" || echo "  FAIL $f.xml missing"; done
echo "  gtk theme : $(sed -n 's/.*ThemeName" type="string" value="\([^"]*\)".*/\1/p' $X/xsettings.xml | head -1)"
echo "  wallpaper : $(sed -n 's/.*last-image" type="string" value="\([^"]*\)".*/\1/p' $X/xfce4-desktop.xml | head -1)"
echo "  screen    : $(cat /root/.vnc/geometry 2>/dev/null)"
echo "  live gtk  : $(timeout 4 xfconf-query -c xsettings -p /Net/ThemeName 2>/dev/null || echo 'xfconf unreachable (files still apply)')"
echo "[*] Session snapshot:"
for p in Xvnc dbus-daemon xfconfd xfsettingsd xfce4-session xfwm4 xfce4-panel xfdesktop plank xfce4-terminal xterm; do
  pgrep -x "$p" >/dev/null 2>&1 && echo "  UP   $p" || echo "  DOWN $p"
done
# (5) keep the launcher alive so dbus-run-session keeps the bus up
while kill -0 "$SPID" 2>/dev/null || pgrep -x xfwm4 >/dev/null 2>&1; do sleep 5; done
