#!/bin/sh
# rikkiti-session — bring up a full Rikkiti Wayland session (compositor + shell +
# session services). Invoked by greetd (or any display manager) as the session
# command; see install/usr/share/wayland-sessions/rikkiti.desktop and
# docs/04-session-glue.md.
#
# Flow: set env → ensure a session D-Bus → start secrets (gnome-keyring) + SSH
# agent (gcr-ssh-agent) → exec the compositor, which spawns the panel
# (RIKKITI_STARTUP) and the autostart list (copyq, nm-applet, portals, …).
set -eu

# ---- environment ----------------------------------------------------------
export XDG_SESSION_TYPE=wayland
export XDG_SESSION_DESKTOP=rikkiti
# "Rikkiti:GNOME" — colon-separated per the XDG spec (consumers match any token).
# "Rikkiti" keeps our portal routing (rikkiti-portals.conf matches the first
# token); the "GNOME" token makes Chromium/Electron apps (Brave, Chrome, Signal
# Desktop, VS Code, Slack, …) auto-select the gnome-libsecret password backend
# and store secrets in our gnome-keyring instead of a plaintext "basic" store —
# they only do that for desktops they recognise, and "Rikkiti" alone isn't one.
export XDG_CURRENT_DESKTOP=Rikkiti:GNOME
# xdg-open's detectDE() only matches XDG_CURRENT_DESKTOP via the `GNOME*` PREFIX,
# so "Rikkiti:GNOME" (GNOME kept SECOND for the portal/keyring above) leaves it
# undetected → it falls to open_generic and fails to launch the registered handler
# (clicking an image/video does nothing). Its next fallback is this deprecated
# GNOME-2 var → set it so xdg-open resolves DE=gnome → `gio open` (reads the same
# mimeapps defaults) for EVERY caller, without disturbing the Rikkiti-first ordering.
export GNOME_DESKTOP_SESSION_ID="${GNOME_DESKTOP_SESSION_ID:-this-is-deprecated}"
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
# Keyboard: honour /etc/default/keyboard (set by the installer) as the XKB default so
# the compositor and apps start in the chosen layout, not us. A per-user Settings
# choice (input.conf) still overrides this — it's only the fallback for a fresh login.
if [ -r /etc/default/keyboard ]; then
	. /etc/default/keyboard
	export XKB_DEFAULT_LAYOUT="${XKBLAYOUT:-us}" XKB_DEFAULT_MODEL="${XKBMODEL:-pc105}"
	export XKB_DEFAULT_VARIANT="${XKBVARIANT:-}" XKB_DEFAULT_OPTIONS="${XKBOPTIONS:-}"
fi
# Toolkit Wayland hints. The goal is: prefer native Wayland, fall back to X11
# (XWayland) for apps that need it — never force a backend that can't fall back.
export MOZ_ENABLE_WAYLAND=1               # Firefox/Thunderbird native Wayland
export QT_QPA_PLATFORM="wayland;xcb"      # Qt: try Wayland (needs qtwayland), else XWayland
export ELECTRON_OZONE_PLATFORM_HINT=auto  # Electron (VSCode/Discord/…): Wayland if available, else X11
export CLUTTER_BACKEND=wayland
export _JAVA_AWT_WM_NONREPARENTING=1      # Java/AWT/Swing (e.g. SimpleHelp) under a non-reparenting WM
# Don't let SDL games minimize themselves when a FULLSCREEN window loses focus
# (SDL's default). On a workspace desktop, switching away from a fullscreen game
# (Super+number) would otherwise minimize it — you'd return to an empty
# workspace and have to restore from the taskbar. Off = the game just stays on
# its (now-hidden) workspace and reappears when you switch back. (SDL2 + SDL3.)
export SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS=0
# NOT set on purpose: GDK_BACKEND (let GTK auto-pick wayland/x11) and
# SDL_VIDEODRIVER (forcing it breaks games that need X11; SDL auto-detects).
# Cursor theme/size from Settings (appearance.conf), so the compositor's own pointer
# + XWayland clients match the user's choice at login. Falls back to Breeze_Light @ 24.
_appearance="${XDG_CONFIG_HOME:-$HOME/.config}/rikkiti/appearance.conf"
_ctheme="$(sed -n 's/^[[:space:]]*cursor_theme[[:space:]]*=[[:space:]]*//p' "$_appearance" 2>/dev/null | tail -1)"
_csize="$(sed -n 's/^[[:space:]]*cursor_size[[:space:]]*=[[:space:]]*//p' "$_appearance" 2>/dev/null | tail -1)"
# Breeze_Light = the white "snow" pointer, and Rikkiti's default. NOTE: Debian ships
# NO "Breeze_Snow" — that is KDE's upstream name; Debian's breeze-cursor-theme gives
# `breeze_cursors` (Name=Breeze, dark) and `Breeze_Light` (Name=Breeze Light, white).
# Must stay in step with DEFAULT_CURSOR in skald_settings, and breeze-cursor-theme is
# a rikkiti-desktop DEPENDS — a missing default cursor theme means NO POINTER.
export XCURSOR_THEME="${XCURSOR_THEME:-${_ctheme:-Breeze_Light}}"
export XCURSOR_SIZE="${XCURSOR_SIZE:-${_csize:-24}}"
# virtio-gpu's hardware cursor plane renders flipped/offset (QEMU/VM) — force a
# software cursor there so the visible pointer matches the real one. Real GPUs
# (intel/amd/nvidia) keep hardware cursors for efficiency.
for _drv in /sys/class/drm/card*/device/driver; do
	case "$(basename "$(readlink -f "$_drv" 2>/dev/null)" 2>/dev/null)" in
		virtio*) export WLR_NO_HARDWARE_CURSORS=1 ;;
	esac
done

# ---- session D-Bus --------------------------------------------------------
# The tray, notifications, secrets, and portals all need ONE session bus shared
# with the apps. If the login stack didn't already give us one (systemd --user),
# re-exec ourselves wrapped in a fresh one so everything below shares it.
if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ] && [ -z "${RIKKITI_HAVE_BUS:-}" ]; then
	export RIKKITI_HAVE_BUS=1
	exec dbus-run-session -- "$0" "$@"
fi
# Export our Wayland/desktop env to the bus so D-Bus-activated services
# (portals, etc.) and `systemctl --user` units inherit it.
command -v dbus-update-activation-environment >/dev/null 2>&1 && \
	dbus-update-activation-environment --systemd \
		XDG_CURRENT_DESKTOP XDG_SESSION_TYPE XDG_RUNTIME_DIR 2>/dev/null || true

# ---- secrets: gnome-keyring (Secret Service + PKCS#11) --------------------
# pam_gnome_keyring (in greetd's PAM stack) unlocks it with the login password;
# --start connects to that daemon and exports its control vars for this session.
# SSH is intentionally NOT requested here — gcr-ssh-agent (below) owns that now.
if command -v gnome-keyring-daemon >/dev/null 2>&1; then
	eval "$(gnome-keyring-daemon --start --components=secrets,pkcs11 2>/dev/null)" || true
	export GNOME_KEYRING_CONTROL GNOME_KEYRING_PID
fi

# ---- SSH agent: gcr-ssh-agent --------------------------------------------
# The modern split-out of gnome-keyring's SSH agent (gcr-4). Serves keys over
# SSH_AUTH_SOCK and prompts to unlock them via the keyring. ssh adds keys on
# first use (set `AddKeysToAgent yes` in ~/.ssh/config to persist them).
for gcr in /usr/libexec/gcr-ssh-agent /usr/lib/gcr-ssh-agent /usr/lib/*/gcr-ssh-agent; do
	if [ -x "$gcr" ]; then
		mkdir -p "$XDG_RUNTIME_DIR/gcr"
		# Subshell so gcr-ssh-agent reparents to init (it daemonizes) — otherwise its
		# launcher zombies under the compositor, which doesn't reap children.
		( "$gcr" "$XDG_RUNTIME_DIR/gcr" >/dev/null 2>&1 & )
		export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/gcr/ssh"
		break
	fi
done

# ---- XDG user dirs --------------------------------------------------------
# Create ~/Documents, ~/Downloads, ~/Pictures, … (+ ~/.config/user-dirs.dirs) so
# the file manager has its standard places/bookmarks. Idempotent; no-op once set.
command -v xdg-user-dirs-update >/dev/null 2>&1 && xdg-user-dirs-update 2>/dev/null || true

# ---- GTK sidebar bookmarks -------------------------------------------------
# First login: seed the GTK bookmarks (Thunar / file-chooser sidebar) with the
# standard places. Absolute file:// URIs are per-user, so this can't live in
# /etc/skel — generate once, then never touch (user edits are sacred).
if [ ! -f "$HOME/.config/gtk-3.0/bookmarks" ]; then
	mkdir -p "$HOME/.config/gtk-3.0"
	[ -f "$HOME/.config/user-dirs.dirs" ] && . "$HOME/.config/user-dirs.dirs" 2>/dev/null || true
	{
		echo "file://${XDG_DOCUMENTS_DIR:-$HOME/Documents} Documents"
		echo "file://${XDG_DOWNLOAD_DIR:-$HOME/Downloads} Downloads"
		echo "file://${XDG_MUSIC_DIR:-$HOME/Music} Music"
		echo "file://${XDG_PICTURES_DIR:-$HOME/Pictures} Pictures"
		echo "file://${XDG_VIDEOS_DIR:-$HOME/Videos} Videos"
	} > "$HOME/.config/gtk-3.0/bookmarks"
fi

# ---- GTK theming ----------------------------------------------------------
# Regenerate ~/.config/gtk-{3,4}.0/settings.ini + gtk.css from the Rikkiti config
# (accent + dark from appearance.conf; Noto Sans + Papirus defaults) so GTK apps
# are themed out-of-box without ever opening Settings. Headless, fast, idempotent.
command -v rikkiti-settings >/dev/null 2>&1 && rikkiti-settings --apply-gtk >/dev/null 2>&1 || true

# ---- greeter theme cache --------------------------------------------------
# Publish this user's accent + wallpaper to /var/lib/rikkiti/greeter so the login
# screen shows their own theme next time (the greeter runs as _greetd and can't
# read 0700 home dirs). Best-effort; never blocks login.
command -v rikkiti-greeter-export >/dev/null 2>&1 && rikkiti-greeter-export 2>/dev/null || true

# One-time: adopt rikkiti-view as the default image handler (marker-guarded, so
# a user who later picks a different viewer is never overridden). Cheap no-op
# after the first run.
rikkiti-view-mkdefault 2>/dev/null || true

# ---- compositor + shell ---------------------------------------------------
# rikkiti-comp spawns the panel (RIKKITI_STARTUP) and reads ~/.config/rikkiti/
# autostart.conf (copyq, nm-applet, the polkit agent, …).
export RIKKITI_STARTUP="${RIKKITI_STARTUP:-rikkiti-panel}"
# Session log: without this, the compositor's stderr lands on the greetd VT
# (tty7) where it scrolls away unread — every wlr_log line (constraint/input
# diagnostics, crash forensics) was unrecoverable. Keep this session's log +
# the previous one under XDG state.
LOGDIR="${XDG_STATE_HOME:-$HOME/.local/state}/rikkiti"
mkdir -p "$LOGDIR"
[ -f "$LOGDIR/comp.log" ] && mv -f "$LOGDIR/comp.log" "$LOGDIR/comp.log.1"
exec rikkiti-comp >"$LOGDIR/comp.log" 2>&1
