sway-services icon indicating copy to clipboard operation
sway-services copied to clipboard

Is systemd-notify from sway config the best way to wait for sway's readyness ?

Open xdbob opened this issue 6 years ago • 9 comments

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.

xdbob avatar Aug 12 '19 06:08 xdbob

sd_notify internal support probably won't happen: https://github.com/swaywm/sway/pull/3486

xdbob avatar Aug 31 '19 08:08 xdbob

The sway devs seem unlikely to add native systemd support any time soon. I think this issue can be closed.

markstos avatar Nov 13 '20 15:11 markstos

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:

  1. In sway.seevice instead of BindsTo=sway-session.target use PartOf=sway-session.target.
  2. Remove RefuseManualStart=yes from sway-session.target.
  3. Remove StopWhenUnneeded=yes from sway-session.target.
  4. In the config file add && systemctl --user start sway-session.target.
  5. In the config file remove && systemd-notify --ready.
  6. Add BindsTo=sway.service to sway-session.target.

This means that:

  • sway.service starts, but does not pull sway-session.target with it.
  • At some point, sway is considered ready. At that point, instead of systemd-notify, start the sway-session.target, which pulls in the rest of the systemd units.
  • If sway-session.target is stopped, sway.service is stopped as well, since it's PartOf=sway-session.target.
  • If sway.service gets stopped, sway-session.target is stopped as well, since it BindsTo=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.

alextsits avatar Jan 21 '22 17:01 alextsits

I can provide a PR implementing the above by the way. I already use that setup in my workstation.

alextsits avatar Jan 21 '22 17:01 alextsits

@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 avatar Jan 21 '22 18:01 markstos

@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.

alextsits avatar Jan 22 '22 12:01 alextsits

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

markstos avatar Jan 24 '22 21:01 markstos

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.

tinywrkb avatar Jan 24 '22 22:01 tinywrkb

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

dvdhrm avatar Jul 11 '23 10:07 dvdhrm