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.