layered-soul/skills/bootable-usb-images/references/xfce-icon-theme-branding-failures.md
Sam & Claude 4d8ce07fa7 docs: apply Prettier to current markdown (Sam & Codex)
Normalize markdown formatting after the latest main updates.\n\nChecks: python3 scripts/layered_soul.py validate .; npx --yes prettier@3 --check '**/*.md'; git diff --check.
2026-06-14 01:48:32 +02:00

5.7 KiB

XFCE Icon Theme / Branding Failures on FreeBSD Live USB

Use this when the desktop starts (XFCE session, panel, window manager visible) but icons, wallpaper, or branded panel elements are wrong: missing Start-button icon, default wallpaper instead of branding, blank launcher icons in panel or Whisker menu.

This is a different failure class from Xorg/XKB/session startup — the desktop is running, but the visual contract is broken.

Live-session diagnostics

On the running USB, capture these first:

# What icon themes exist and have cached?
ls -d /usr/local/share/icons/*/
for d in /usr/local/share/icons/*/; do
  echo "$d: $(ls "$d"icon-theme.cache 2>/dev/null && echo cached || echo NO_CACHE)"
done

# Are the brand icons in hicolor?
find /usr/local/share/icons/hicolor -name 'clawdie*' 2>/dev/null
ls -l /usr/local/share/clawdie-iso/icons/ 2>/dev/null

# What icon theme is XFCE actually using?
xfconf-query -c xsettings -p /Net/IconThemeName 2>/dev/null
xfconf-query -c xfce4-panel -p /plugins/plugin-1/button-icon 2>/dev/null

# Is the branded wallpaper present?
ls -l /usr/local/share/clawdie-iso/wallpapers/clawdie-operator-bg.png 2>/dev/null
xfconf-query -c xfce4-desktop -l 2>/dev/null | grep 'last-image'

Root cause patterns

1. XFCE plugins reject absolute icon paths

Symptom: Whiskermenu Start button shows a broken/missing icon glyph despite the PNG existing on disk.

Root cause: XFCE panel plugins (whiskermenu, launcher) do not reliably load absolute icon paths like /usr/local/share/clawdie-iso/icons/clawdie-start.png. They resolve icons by themed name through the standard icon-theme lookup chain (hicolor → Adwaita → Papirus → ...).

Fix in build.sh:

  • Set button-icon to a themed name: clawdie-start (not an absolute path)
  • Install the icon PNG+SVG into hicolor/48x48/apps/, hicolor/64x64/apps/, and hicolor/scalable/apps/
  • Run gtk-update-icon-cache -f -t /usr/local/share/icons/hicolor after installing

2. Brand icons not in the icon theme search path

Symptom: themed icon name resolves to nothing — icon appears blank — even though the file exists at a custom absolute path.

Root cause: Installing icons only into a custom directory like /usr/local/share/clawdie-iso/icons/ places them outside the icon theme search path. XFCE looks up themed names by scanning /usr/local/share/icons/<theme>/<size>/<category>/. hicolor is the fallback theme.

Fix in build.sh:

mkdir -p /usr/local/share/icons/hicolor/48x48/apps
mkdir -p /usr/local/share/icons/hicolor/64x64/apps
mkdir -p /usr/local/share/icons/hicolor/scalable/apps
install -m 0644 clawdie-start.png /usr/local/share/icons/hicolor/48x48/apps/clawdie-start.png
install -m 0644 clawdie-start.png /usr/local/share/icons/hicolor/64x64/apps/clawdie-start.png
install -m 0644 clawdie-start.svg /usr/local/share/icons/hicolor/scalable/apps/clawdie-start.svg
gtk-update-icon-cache -f -t /usr/local/share/icons/hicolor

Also keep the original absolute-path copy in /usr/local/share/clawdie-iso/icons/ for diagnostic inspection; it just can't be the primary resolution path.

3. XFCE creates monitor-specific keys after xfdesktop starts

Symptom: wallpaper defaulting to stock (or missing) instead of the Clawdie branding defined in the panel-skel XML — even though the XML is correct and the wallpaper file exists.

Root cause: On first boot, xfdesktop creates monitor-specific backdrop keys (e.g. /backdrop/screen0/monitorDP-1/workspace0/last-image) that don't exist in the pre-seeded skeleton XML. The skeleton only has workspace0 and workspace1 keys, which xfdesktop may ignore in favor of monitor-specific ones it creates at runtime.

Fix: Add a post-login visual guard script that runs from XDG autostart and re-applies theme, panel branding, and wallpaper at 3, 7, and 15 seconds after login. This catches monitor-specific keys created during the startup race and writes the correct values into whichever keys exist at each tick.

Guard script pattern (best-effort, never fails the session):

# Run at 3s, 7s, 15s after login via XDG autostart
xfconf-query -c xfce4-desktop -p "${base}/last-image" -s "$WALLPAPER" 2>/dev/null || \
  xfconf-query -c xfce4-desktop -p "${base}/last-image" -n -t string -s "$WALLPAPER" 2>/dev/null || true

4. Icon caches stale for rarely-used themes

Symptom: application launcher icons (pcmanfm, xfce4-terminal, firefox) blank in panel launchers or Whisker menu despite applications installed correctly.

Root cause: gtk-update-icon-cache was only run for a fixed list of known themes. Applications install icons into hicolor (or other themes) during pkg install, but their directories weren't in the hardcoded list.

Fix: scan ALL directories under /usr/local/share/icons/ dynamically:

for _icon_theme_dir in /usr/local/share/icons/*/; do
    [ -d "$_icon_theme_dir" ] || continue
    _theme_name=$(basename "$_icon_theme_dir")
    gtk-update-icon-cache -f -t "/usr/local/share/icons/${_theme_name}" || true
done

Build-time checks (before flashing)

When building the image, verify the icon contract:

# Icon caches exist for all themes
for d in /mnt/usr/local/share/icons/*/; do
  ls "$d"icon-theme.cache >/dev/null 2>&1 || echo "MISSING CACHE: $d"
done

# Brand icon installed into hicolor
ls -l /mnt/usr/local/share/icons/hicolor/48x48/apps/clawdie-start.png
ls -l /mnt/usr/local/share/icons/hicolor/scalable/apps/clawdie-start.svg

# Panel XML uses themed name, not absolute path
grep button-icon /mnt/home/clawdie/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml

# Visual guard installed and executable
ls -l /mnt/usr/local/bin/clawdie-xfce-visuals-guard.sh
ls -l /mnt/usr/local/etc/xdg/autostart/clawdie-xfce-visuals-guard.desktop