Skip to content

fix: replace per-user skel autostart with gated system-wide autostart#23

Merged
bketelsen merged 1 commit into
mainfrom
fix/gated-system-autostart
Jul 5, 2026
Merged

fix: replace per-user skel autostart with gated system-wide autostart#23
bketelsen merged 1 commit into
mainfrom
fix/gated-system-autostart

Conversation

@bketelsen

Copy link
Copy Markdown
Contributor

Fixes frostyard/snosi#355

Problem

data/meson.build installed an unconditioned copy of the launcher .desktop to /etc/skel/.config/autostart/, so every user ever created on a snow system got the wizard autostarted on first login — live-session users (colliding with the installer; dakota-iso had to manually rm it from skel), installer-created users, and accounts added years later. Suppression was purely reactive: the app deleted the per-user copy only when that user completed the flow.

Mechanism change

Before After
Per-user copy via /etc/skel/.config/autostart/ Single system entry in /etc/xdg/autostart/ (XDG-standard, never copied per-user)
No launch gating Exec=snow-first-setup --autostart; main() exits 0 before any GTK/resource loading when the completion marker exists or backend.is_live_session() is true
Completion = delete per-user file (remove-autostart-file) Completion = write marker $XDG_CONFIG_HOME/snow-first-setup.done (complete-setup script); also rm -f's the legacy skel-copied entry as upgrade cleanup
  • --autostart is registered as a GApplication main option so a gated-through launch (fresh user, first login) parses cleanly.
  • The OEM snow user path (Session=firstsetup) and explicit/manual launches are unaffected — the gate applies only to --autostart invocations.
  • Live sessions no longer need to scrub skel: the gate reuses the existing is_live_session() (snow-linux.live=1).

Upgrade / double-launch analysis

  • Users provisioned before this change still have ~/.config/autostart/org.frostyard.FirstSetup.autostart.desktop. It has the same filename as the new system entry, so per the XDG autostart spec the per-user file shadows /etc/xdg/autostart — no double launch. If both somehow fired, org.frostyard.FirstSetup is a single-instance Adw.Application, so the second activation folds into the first.
  • Their per-user copy has no --autostart flag, so legacy behavior persists for them until they finish the wizard, at which point complete-setup removes the legacy file and writes the marker.
  • debian/snow-first-setup.maintscript rm_conffiles the obsolete skel conffile on package upgrade (moot for fresh image builds, correct for any dpkg upgrade path).
  • New users created after this change never get anything in their home; the wizard appears once, and the marker suppresses it forever after.

Verification

  • meson setup --prefix=/usr --sysconfdir=/etc + ninja: clean build; DESTDIR install confirmed the entry lands at etc/xdg/autostart/org.frostyard.FirstSetup.autostart.desktop (with Exec=snow-first-setup --autostart) and nothing under skel/.
  • meson test: both desktop-file-validate tests pass (launcher + new autostart entry).
  • Gate exercised directly: with marker present, main.main([... --autostart]) returns 0 before resource loading; without marker, is_setup_complete() is False.
  • complete-setup exercised against a fake $HOME: writes the marker, removes a pre-seeded legacy autostart file, exit 0; shellcheck clean.
  • FirstSetupApplication constructed successfully with the new --autostart option registered (no short-flag collision).
  • Not verified: a full GUI login session (no display in this environment), and the dpkg upgrade path end-to-end.

🤖 Generated with Claude Code

The wizard's autostart entry was installed to
/etc/skel/.config/autostart/, so every user ever created (live-session
users, installer-created users, accounts added years later) received a
private copy that launched the wizard unconditionally on first login.
Suppression was purely reactive: the app deleted the per-user copy only
when that user completed the flow, and live media had to manually rm the
file from skel.

Mechanism change:

- Install a single autostart entry to /etc/xdg/autostart/ (XDG-standard,
  never copied per-user). Its Exec passes --autostart.
- Gate at startup: with --autostart, main() exits 0 before any
  GTK/resource loading when the per-user completion marker
  ($XDG_CONFIG_HOME/snow-first-setup.done) exists or when running a live
  session (existing backend.is_live_session(), snow-linux.live=1).
- On completion, write the marker instead of deleting a file: the
  remove-autostart-file script becomes complete-setup, which touches the
  marker and also rm -f's the legacy skel-copied per-user entry as
  upgrade cleanup (rm -f, since new users never have it).
- Upgrade safety: pre-0.2.16 users keep a per-user copy with the same
  filename, which shadows the /etc/xdg/autostart entry per the XDG
  autostart spec, so no double launch; GApplication single-instance
  (org.frostyard.FirstSetup) guards any residual race. A dpkg
  maintscript removes the now-obsolete skel conffile on package upgrade.

The OEM snow-user path (Session=firstsetup) and explicit launches are
unaffected: the gate only applies to --autostart invocations.

Fixes frostyard/snosi#355

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bketelsen
bketelsen merged commit c4a69b4 into main Jul 5, 2026
1 check failed
@bketelsen
bketelsen deleted the fix/gated-system-autostart branch July 5, 2026 02:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

first-setup autostart is copied to every user via /etc/skel; should be a gated system-level autostart

1 participant