Skip to content
omarchyFIELD GUIDE
PRACTICAL KNOWLEDGE / FIELD GUIDE

Autostart apps and background tasks without duplicate processes

Choose between session startup and a packaged user service, add one app safely, diagnose ownership and logs, and remove the right startup entry.

Based on public documentation; not hardware-tested. Match the instructions to your version and hardware.

You want Files to be ready after login and a sync tool to run in the background. Putting both commands into every startup file can produce duplicate windows, a second service competing for a port, or tasks that unexpectedly survive logout. Start by choosing who owns the process.

This guide follows Omarchy’s pinned 4.0.0.alpha Lua helpers. Confirm ~/.config/hypr/autostart.lua is loaded by your personal entry point. Syncthing below is an optional upstream example, not a claim that every Omarchy installation includes it. All experiments should start with known existing application and service states.

Hyprland session starts
→ Omarchy default startup + personal autostart.lua
→ o.launch_on_start → uwsm-app → session application
systemd user manager
→ enabled user unit → supervised background service
desktop autostart / app preferences / hooks
→ other possible startup owners
Need Start with Reason
Open an ordinary graphical app when the desktop starts Personal autostart.lua Follows the graphical session
Run an installed daemon with a supplied service Its packaged user unit Known stop/restart behaviour and journal
Run a task periodically A suitable scheduler/timer Login is not a recurring schedule
Start a machine-wide service before login A properly scoped system unit Different owner and permissions; outside this exercise

o.launch_on_start registers a hyprland.start callback and uses uwsm-app. It is not an exec line that runs continuously on every configuration reload. It also does not deduplicate another independent startup owner or automatically restart a crashed app. Helper implementation

A user service is not necessarily a graphical-session service. Its lifetime depends on targets, dependencies, other logins and whether lingering is enabled. An enabled default.target service can outlive the desktop. Omarchy’s own sleep-lock unit explicitly uses PartOf=graphical-session.target and waits for session environment; do not infer those properties for every user unit. Omarchy service example

2. Inventory startup owners before adding one

Section titled “2. Inventory startup owners before adding one”

For Files:

Terminal window
command -v nautilus
grep -n 'nautilus' ~/.config/hypr/autostart.lua
grep -R -n 'nautilus' ~/.config/autostart /etc/xdg/autostart 2>/dev/null
systemctl --user list-unit-files --type=service

Look at the relevant entries, not just whether a string appears. A comment is not an enabled launch. A desktop entry can use Hidden, OnlyShowIn or other conditions. An application can also have its own “start at login” switch, or a post-boot hook can start it.

Omarchy already starts the Shell, monitor watcher and automount helper in its defaults. Adding another copy of one of those is not personal autostart customization. Inspect defaults when the app or service looks like part of the desktop. Default startup

Record whether the chosen app is already running, which launcher starts it, and what you will remove after the exercise. For a daemon, inspect the supplied unit first. Use one owner for the same instance/configuration.

3. Case: open Files once when entering the desktop

Section titled “3. Case: open Files once when entering the desktop”

First launch Files manually and confirm it works. Back up the existing personal file under a fresh name:

Terminal window
cp -i ~/.config/hypr/autostart.lua ~/.config/hypr/autostart.lua.before-autostart

Add only this line through Setup → Config → hypr/autostart.lua:

o.launch_on_start("nautilus")

Keep the rest of the file. Do not add a trailing & merely to “make it background”: the helper already launches through the session application launcher. If the app requires arguments, test the exact command independently first; shell quoting, application arguments and Lua quoting remain distinct.

Save and exit. A reload is not the login test. It should not be used to prove a start-event action ran. Save all work, log out normally and log back in when convenient. Check that Files is available, the ordinary Files shortcut still works, and there is no second independent launch owner.

Nautilus can reuse a running application instance; counting its windows does not by itself count startup commands. The useful result is the expected app on login, without duplicate actions, error messages or a second ownership path. If it opens on the wrong workspace, use a separately verified window rule; do not assume startup order determines reliable placement.

4. Diagnose a command that works in a terminal but not at login

Section titled “4. Diagnose a command that works in a terminal but not at login”

Interactive shell aliases and functions are not automatically standalone programs. Startup may use a different working directory, search path or environment from your terminal.

Symptom Check
“Command not found” command -v, actual executable path, not an alias
Relative file missing Use a verified absolute path or explicit working directory
GUI cannot connect Is it starting within the graphical session with the right display environment?
App starts then exits Run the same command manually and read its error
Only a reload appears ineffective Start callback requires a new compositor session
Wrong workspace Inspect window class and startup placement rules

Inspect a relevant process using its observed PID:

Terminal window
ps -o pid,ppid,args -p 12345

Replace 12345; it is not a real PID to target. For a user service, inspect the relevant journal and configured environment. A limited manager check is:

Terminal window
systemctl --user show-environment | grep -E '^(WAYLAND_DISPLAY|DISPLAY|PATH)='

Do not publish the manager’s complete environment: it can contain sensitive values. Changing a shell export also does not retroactively change an already-running service’s environment. Diagnose the owner before importing variables or restarting unrelated desktop services.

5. Case: use the supplied service for an optional sync daemon

Section titled “5. Case: use the supplied service for an optional sync daemon”

If you already installed Syncthing and want it managed in the background, inspect its user unit rather than adding syncthing to the Lua file too:

Terminal window
command -v syncthing
systemctl --user cat syncthing.service
systemctl --user is-enabled syncthing.service
systemctl --user is-active syncthing.service

Record the initial enabled/active states. If the unit is absent, stop this branch and consult your installed package’s instructions; do not invent a similarly named service or assume a system unit is the same thing. A package may supply syncthing@USER.service for a system manager and syncthing.service for a user manager; mixing them can start two owners.

If the intended user unit exists and no other owner runs this configuration, start it for the current session first:

Terminal window
systemctl --user start syncthing.service
systemctl --user status syncthing.service --no-pager
journalctl --user -u syncthing.service -n 50 --no-pager

Then check the actual application’s local interface and a disposable sync folder. “Active” confirms supervision, not successful synchronization. This article does not configure peers or authorize changes to your real folders. Only after the application works, enable future startup:

Terminal window
systemctl --user enable syncthing.service

start affects now; enable installs future startup links. Neither is the same as enabling a browser to open on login. A system unit command without --user addresses a different manager. Syncthing’s upstream startup guide

Do not enable lingering just to make a login app work. It changes when the user manager and its enabled services may run, including before login. Likewise, a service remaining alive during another user login is not proof that the desktop failed to clean up its own applications.

6. Duplicate processes: find owners, not just counts

Section titled “6. Duplicate processes: find owners, not just counts”
Observation Likely next investigation
Two windows on every login App preference plus Lua/desktop entry
Service reports address/port already in use Another daemon owner or separate configuration
Killing a process makes it return Service restart policy or a supervising launcher
Several processes share one app Helpers, renderer or supervision tree may be normal
Service works only after opening a terminal Path, environment or manual second start

Use the service status and process tree to identify the parent. Do not use a broad pkill as the permanent fix: it does not remove the future startup entry and can interrupt real work. Remove or disable the duplicate owner, then stop that owner’s process in the application’s supported way. For supervised services use systemctl --user stop on the verified unit.

If converting a daemon from Lua startup to its service, remove the old line, stop the old instance normally, confirm it released its resources, and then start the service. Keep its configuration and data; changing startup ownership does not require reinstalling the app.

For Files, remove only the added o.launch_on_start line. Saving affects future startup; close the present test window normally if desired. If using the backup, compare later changes first. Test one subsequent login and confirm it no longer launches automatically while the manual shortcut still works.

For the optional service, restore the recorded states. If it was previously disabled and inactive:

Terminal window
systemctl --user disable --now syncthing.service

If it was already enabled or running, do not apply that undo blindly. Restore only what this exercise changed. disable alone does not stop the current process, and stop alone does not remove future startup. Neither deletes synced data or application configuration.

Keep a short note: executable, startup owner, configuration path, expected lifetime, log source and undo action. That makes later login problems much easier to diagnose. Continue with configuration maintenance and awake behaviour for long tasks. The guide is source-reviewed, not tested on a live Omarchy system.