For some reason, that I don’t even remember, I wanted to have my user daemons started by systemd. Partially as an exercise, partially to have them auto-restart and to get a bit more familiar with the concept.

The first task to get this done, is to start sway (or whatever compositor you use) via systemd, so we don’t run into any timing problems.

While logging into a tty and starting sway works fine, I decided I want to directly boot into sway. My boot queries for the disk encryption passphrase on boot either way.

Start the user instance

Most of what I wanted to use is done by the systemd --user instance started for every user on login.

This is primarily done by a systemd_pam pam module.

I couldn’t find a good way to automatically do this on startup and hand myself the tty. It seems like the easiest way to do this, is a Display Manager. I chose to use sddm but it doesn’t really matter. I’ve recently seen greetd and would probably use it to setup the system fresh.

Follow the sway wiki

The sessions offered by SDDM are controlled by .desktop files. They are pretty simple and I based mine on the example from the sway wiki.

The final piece to we need to add, for the system to boot to sway, is the sway.service file. The version in the sway wiki works for now.

At this point we boot straight into sway \o/.

“Improve” on the sway wiki

So far we started sway via systemd. But there’s nothing that changes yet. Sway still starts all of it’s daemons from the exec statements in the config file. And so are things called via exec keybinds (and their children).

Remember to remove the configuration of these services from the sway config!

swayidle

swayidle has an example in the sway wiki.

so we add our swayidle.service file. systemctl --user enable ... it and you are fine.

swaybg

Mostly for exercise I wanted to start swaybg from systemd as well. And not have sway autostart it. This allows me to restart it (systemctl --user restart swaybg.service) without reloading sway. But I haven’t used that since pretty much after I got it set up :)

It works largely like swayidle, we also have to add swaybg.service file.

When we add (and enable) this service, systemd will autostart it, after sway is started.

swaybar

This is where things get tricky. There might be more than one swaybar at the same time (different configs/screens). Luckily there’s template unit files, so we can start roughly with the same approach and add a swaybar@.service.

Wen then enable it with:

`sytemctl --user enable swaybar@bar-0.service`

If you follow along, at this point you will notice, that things aren’t quite as easy, as we’d hope.

Disabling the swaybar started by sway isn’t quite intuitive, I set the swaybar_command to /bin/true resulting in this snippet.

At this point, you won’t have any swaybar at all. The systemd service fails. There reason being, that we are missing an environment variable.

sway.service

Getting this environment variable loaded into our systemd instance, can be done with some minor changes to the sway config that import the environment into our systemd --user instance.

For the systemd-notify to work, we also need to slightly adjust sway.service. This prevents a race condition between sway startup, and our daemons being started.

sddm

Until now, we are still greeted by sddm and have to login to access our desktop. To avoid this, we can add a simple configuration file and have it autostart a login and our session.

Applications

Some of the applications I open every so often are also pushed into their own systemd units. The only real reason for this to exist is that systemd-cgls provides a nice overview, where any currently running process is spawned from.

Browsers

The only one I autostart is qutebrowser. I use scripts placed into $PATH to start them via wofi otherwise.

Alacritty

This one is a bit silly, but I wanted to try it out. This of course starts with a alacritty@.service file.

It’s designed to open multiple instances at the same time, and disambguiate them via UUIDs generated on the fly.

The KillMode=none in the unit file prevents systemd from killing lingering processes started by the shell in the terminal in some way (e.g. zathura &).

It works as intended and so far I have no problems at all.