alebastr / sway-systemd

Systemd integration for Sway session
MIT License
134 stars 12 forks source link

Best way to start `foot` socket? #13

Open markstos opened 2 years ago

markstos commented 2 years ago

The foot terminal is adding systemd socket activation:

https://codeberg.org/dnkl/foot/pulls/890

What's the best way to set up the socket? Note that it's a template unit, so one socket can be set up per Wayland display (relating to #12).

Since it's a template unit, it doesn't seem like an [Install] block will work. It seems that start needs to explicitly be called on the socket file, like systemctl start foot-server@$WAYLAND_DISPLAY.socket.

This is something that this project could potentially take care of, but this project is otherwise agnostic towards specific systemd services, so maybe that's not a feature that's desirable to add here.

If starting the foot socket were to be handled here, I see a couple options:

  1. Unconditionally try to start the foot socket and ignore the error code if the socket can't be found (since not everyone will use foot). This is zero-configuration, runs and the background and doesn't really block anything else from happening. Because it's just launching socket activation and not the the foot server, there's very little overhead.
  2. Add an option or configuration to explicitly enable the foot server. If configured, attempt to start the unit.

Given the somewhat unique case, I think it's worth considering attempting to start the foot socket file.

As a side note on fast foot can launch in client server mode, it's about 10x faster than Alacritty for this test, taking only 10 ms to run!

 time alacritty -e /bin/echo 42
__________________________________________
Executed in   91.19 millis    fish           external

❯ time footclient -e /bin/echo 42
__________________________________________
Executed in   10.38 millis    fish           external
Scrumplex commented 2 years ago

The user can always do this by themselves, by either execing a script in Sway or overriding sway-session.target to Want foot-server@???.service (I don't know if systemd allows inserting env vars into dependencies)

In fact I utilize systemd unit overrides to make sway-session.target Want xdg-desktop-autostart.target: my dotfiles

Otherwise, something like a sway-session@$WAYLAND_DISPLAY.target could be interesting, though I haven't played with template target units.

markstos commented 2 years ago

The user can always do this by themselves

Right. But the user can also set up the entire Sway/systemd integration by themselves, but there's value making things easier to or automatic.

overriding sway-session.target to Want foot-server@???.service (I don't know if systemd allows inserting env vars into dependencies)

As far as I'm aware, it isn't possible to reference a dynamic unit name in in a [Install] block that uses an environment variable not already known to systemd.

Otherwise, something like a sway-session@$WAYLAND_DISPLAY.target could be interesting,

The value of sway-session.target is that several unrelated dependencies can all reference a common target. sway-session@$WAYLAND_DISPLAY.target would be a different target. I agree it would be interesting to have per-display sessions for tools like foot, but I'm not sure how feasible it is.

alebastr commented 2 years ago

AFAIR, my last attempt on a similar feature for foot-server was in vain. Systemd wasn't flexible enough to use dependencies based on the environment variable, and generators - an alternative way of achieving that - run only on daemon startup or reload. sway-session starts too late to generate any of its configuration.

sway-session@$WAYLAND_DISPLAY.target can be bound to the sway-session.target and cause it to start, similar to how that's done for graphical-session.target. In the worst case we'll have to give a different name to the template target, but that's still possible. The problem is that we still need to inherit %i specifier from the template target. I'm not sure things work that way.

Will continue looking into that and maybe ask one of our systemd maintainers if they have any suggestions. I'd love to have some solution before I need to update the foot package.

alebastr commented 2 years ago

So...

 export XDG_CURRENT_DESKTOP=sway
 export XDG_SESSION_TYPE=wayland
 VARIABLES="DISPLAY I3SOCK SWAYSOCK WAYLAND_DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE"
-SESSION_TARGET="sway-session.target"
+SESSION_TARGET="sway-session@$WAYLAND_DISPLAY.target"
 WITH_CLEANUP=""

 print_usage() {
$ systemctl --user cat sway-session@.target
# /usr/lib/systemd/user/sway-session@.target
[Unit]
Description=sway session (display: %i)
Documentation=man:systemd.special(7)
BindsTo=sway-session.target
RefuseManualStart=no

$ systemctl --user cat foot-server@.socket
# /home/alebastr/.config/systemd/user/foot-server@.socket
[Socket]
ListenStream=%t/foot-%i.sock

$ systemctl --user add-wants sway-session@.target foot-server@.socket

The add-wants thing is not the most intuitive way to enable the service, but it works.

This also breaks shutdown of the sway-session.target - it stays alive after sway-session@wayland-1.target is stopped. Apparently BindsTo= is insufficient and I need to look into a better way of stopping the targets. Conflicts=sway-session-shutdown.target trick implemented in gnome-session might be an option. StopWhenUnneded=yes fixed this.

alebastr commented 2 years ago

See #15 for the final solution.

I'm already hesitant about the idea. wayland-session@$WAYLAND_DISPLAY.target in systemd would be much better choice for a generic wayland application as it could be added directly to the foot systemd units. But https://github.com/systemd/systemd/pull/15180 was rejected and I doubt we can revive it.

If that looks good for you, I'll add the documentation and merge.

markstos commented 2 years ago

I'm noting that while I got foot --server to run as a systemd service, I have not be able to use it, because I've not be able to figure how to get it to work with gnome-keyring-daemon. The issue has to do with how SSH_AUTH_SOCK is inherited and passed around.

As I described in the related foot bug report, I was able to get as far as getting the environment variable to appear within the service, but connecting back to gnome-keyring-daemon doesn't work.

https://codeberg.org/dnkl/foot/pulls/890#issuecomment-379233

Before any features are added here to support the "foot --server" use case, it would be good to understand this problem as an example.

For now, I've returned to using exec foot --server in my Sway config. That works fine until foot crashes and doesn't automatically get restarted. Still, this is better than having the SSH agent not work at all!

VannTen commented 2 years ago

Related to this issue : https://github.com/systemd/systemd/pull/22500 TL;DR : template units can reference other templates units in [Install], and all instances will have the relations (target_unit@bar -> service_unit@bar and target_unit@foo -> service_unit@foo).

(Not sure if you're already aware of that, but I know it was not clear for me from the systemd docs, so might be worth pointing out).

alebastr commented 2 years ago

Yep, I'm aware of that and #15 exists. But the problem is that we'd want a generic WantedBy=wayland-session@.target for applications like foot instead of an environment-specific WantedBy=sway-session@.target.

As wayland-session@.target clearly does not belong here, someone would have to convince systemd upstream to standardize that. See also discussion in the systemd issue I mentioned in previous comments.

VannTen commented 1 year ago

So I abandoned the whole multi-session ordeal with footserver.socket and reworked the feature so it will work as other user unit, using graphical-session.target. (see https://codeberg.org/dnkl/foot/pulls/1281 )

Still needs some last details, but I think it's pretty close to be merged.