Is systemd-notify from sway config the best way to wait for sway's readyness ?
I don't like it and I would rather have the NotifyAccess set to either main or exec to avoid any user program write access to the service state.
sd_notify internal support probably won't happen: https://github.com/swaywm/sway/pull/3486
The sway devs seem unlikely to add native systemd support any time soon. I think this issue can be closed.
Using type=notify in sway.service caused me problems. Specifically, there was a program, sshuttle, that I executed from my terminal directly (without using systemd service for it). Well, when I used Ctrl+C to exit the program, my sway session gets teared down with it :)
I bet sshuttle checks if NOTIFY_SOCKET is in it env, and notifies that it's stopping. The notification comes from a child of sway, NotifyAccess is set to all, so yeah, systemd end up stopping sway.service :shrug:.
I haven't found a way to remove NOTIFY_SOCKET from sway's environment. I think this approach is buggy.
I propose the following:
- In
sway.seeviceinstead ofBindsTo=sway-session.targetusePartOf=sway-session.target. - Remove
RefuseManualStart=yesfromsway-session.target. - Remove
StopWhenUnneeded=yesfromsway-session.target. - In the config file add
&& systemctl --user start sway-session.target. - In the config file remove
&& systemd-notify --ready. - Add
BindsTo=sway.servicetosway-session.target.
This means that:
sway.servicestarts, but does not pullsway-session.targetwith it.- At some point, sway is considered ready. At that point, instead of
systemd-notify, start thesway-session.target, which pulls in the rest of the systemd units. - If
sway-session.targetis stopped,sway.serviceis stopped as well, since it'sPartOf=sway-session.target. - If
sway.servicegets stopped,sway-session.targetis stopped as well, since itBindsTo=sway.service.
This will also solve the dependency problem, where the rest of the systemd units (like mako.service) have to use After=graphical-session.target. This will no longer be needed, since those units will start only after sway starts sway-session.target. See https://github.com/xdbob/sway-services/issues/12.
I can provide a PR implementing the above by the way. I already use that setup in my workstation.
@alextsits My ultimate solution was to use the "sway-systemd" project which does not run Sway as a systemd service but provides other systemd integrations:
https://github.com/alebastr/sway-systemd
I don't use this sway-services project anymore.
If I'm running sway, it doesn't make sense to "start" it (it's already running), while "restart" and "stop" would kill my session, so I wouldn't use those systemd commands either.
What I really value is to allow other systemd services to to relate to sway, and the sway-session.target unity provided by sway-systemd provides that.
@markstos "sway-systemd" look interesting, thanks for mentioning it.
What I really value is to allow other systemd services to to relate to sway
I completely agree with this. This is my ultimate goal as well.
I'm not entirely sure how I feel about starting sway itself as a a systemd service. I understand it has its problems, I have already bumped into some of those too. I'm still exploring and evaluating.
At first I thought I wanted to run sway as a systemd service myself, but found it more complex than I expected when I looked into it.
The approach put forth by sway-systemd is not only simpler and easier to understand, it has worked well in practice, avoiding complexities like those encountered above.
Whoever wrote the Sway wiki page on systemd is quite clear that running Sway as a systemd service is not recommended, but then the sway developers are somewhat anti-systemd overall so I take that with a grain of salt.
https://github.com/swaywm/sway/wiki/Systemd-integration
I also looked at this problem today, and I think I might go with something like this
[Service]
Type=forking
PIDFile=sway/pid
ExecStartPre=systemctl --user unset-environment DISPLAY WAYLAND_DISPLAY
ExecStart=/bin/sh -c '/usr/bin/sway &'
And in the end of Sway's config
exec pgrep --exact sway > $XDG_RUNTIME_DIR/sway/pid
Note that pgrep has gained --cgroup option in git, so it would be possible to have more precise matching by keeping the main sway process in a separate cgroup than extra sway processes that the user might run.
The other alternative I thought about is to subscribe and wait on a workspace init event via the IPC.
Another alternative is to use SWAY_NOTIFY_SOCKET rather than NOTIFY_SOCKET:
sway.service:
ExecStart=/usr/bin/env --unset=NOTIFY_SOCKET SWAY_NOTIFY_SOCKET=${NOTIFY_SOCKET} /usr/bin/sway
and then:
sway/config:
exec env NOTIFY_SOCKET=${SWAY_NOTIFY_SOCKET} systemd-notify --ready