Hi,
I spend few hours trying to figure this out without being lame and using large sleep.
The problem is basically this:
- You start sway service and that executed the sway binary,
- You have to set
Environment="XDG_SESSION_ID=1"without it Sway will bail and exits - All other graphical services (redshift, waybar, …etc) that starts after sway.service fails because the wayland display is not yet initialized.
It’s not a bug, it’s like this by design “ddevault” and “emersion” even warn people from not launching sway as a systemd --user service because of that fact it forks and never calls sd_ready or whatever.
SOLUTION:
Simple script I made as a post start command
ExecStartPost=%h/.config/systemd/user/sway-wait-for-wayland-display.sh
the content of the sway-wait-for-wayland-display.sh I put that next to the service fail.
It basically ask systemd what the user’s environment is which is not tied to the running context.
#!/bin/sh
i=1
while [ "$i" -ne 100 ]
do
systemctl --user show-environment | grep WAYLAND_DISPLAY > /dev/null
# Return status of grep is 0 when found 1 if not found
status=$?
# Break loop to skip sleep if found on first try
if [ $status -eq 0 ]; then
echo Display has been found.
break
fi
sleep 0.1s
# Increment
i=$((i + 1))
done
If you are just thinking now "Why the frik he didn’t just poll printenv ?
Jokes on you, once you start runnning service the environment is passed to it and is being static.
You can look at my dotfiles, I made them little bit more complex by splitting them into sway-session-pre target and sway session target similarly as graphical session target.
https://git.sr.ht/~freed00m/dotfiles/tree/master/.config/systemd/user
Else, what do you thing? Is it worth mentioning it upstream? I think this is nice cherry on top of what they have in git repo wiki.