sodiboo / niri-flake

Nix packages and modules for niri
https://github.com/YaLTeR/niri
MIT License
135 stars 13 forks source link

systemd services that depend on niri don't work as expected (maybe solved??) #348

Open e-tho opened 4 months ago

e-tho commented 4 months ago

The systemd integration is quite a mess compared to the Sway and Hyprland modules.

The swayidle service won't start because it doesn't have access to the WAYLAND_DISPLAY variable, and the wbg and waybar services work erratically when binded to graphical-session.target.

I've seen that in your personal configuration, some hacks had to be implemented to get around these problems, but this is far from desirable...

A solution using a session target would be much better integrated with NixOS/Home Manager, as most modules that need integration provide a systemdTarget parameter to set the relevant one. It can also be easily integrated into custom services.

I'm not sure whether these changes can be made directly in the NixOS module or whether they need to be made on the niri side, as the author seems to be leaning towards a different solution for systemd integration that uses a session script and no target.

sodiboo commented 4 months ago

For the systemd unit niri.service, I'm just using the exact file provided by upstream. To be honest, I'm not very knowledgeable in systemd, but you are right that my personal configuration relies on some hacks to get everything working smoothly. It's not all too awful at this point, though. I believe this flake (and my system, i guess) does it "as intended" by upstream, but that could definitely be improved on. I've also experienced waybar behaving erratically when binded to graphical-session.target and that's why my configuration does annoying things to bind it to niri.service instead,

@YaLTeR do you have any input on this? why it's done the way it is now, rather than something more similar to what everyone else seems to be doing? It would definitely be a lot nicer if we could rely on graphical-session.target to start services.

YaLTeR commented 4 months ago

Relying on graphical-session.target is the intended way and, well, it works on my machine (tm). This is what I describe here: https://github.com/YaLTeR/niri/wiki/Example-systemd-Setup

The only reason niri.service.wants is part of that, is to restrict those example services to only start in niri (and not if you log into GNOME for example). If things didn't work, they would start at exactly the same time as niri.service, which is indeed too early, but the graphical-session rules make them start at the correct time.

I'm not sure why it's not working on NixOS.

YaLTeR commented 4 months ago

To elaborate, this is the expected order of events:

  1. niri-session runs and starts niri.service
  2. niri.service ExecStart-s /usr/bin/niri --session, then waits for a notification (Type=notify)
  3. niri imports WAYLAND_DISPLAY and whatnot into the systemd environment:
  4. niri notifies systemd that it is ready: https://github.com/YaLTeR/niri/blob/7b6fa1285475896ad8dbc2f4b11099b0c036e4b7/src/main.rs#L224
  5. systemd now proceeds to start graphical-session.target (since niri.service says Before=graphical-session.target). At this point the environment is filled in and everything is ready
  6. systemd starts everything that has After=graphical-session.target, Requisite=graphical-session.target, i.e. example swaybg.service from the wiki page
e-tho commented 4 months ago

It seems to be a NixOS problem:

It's crazy that this has been around for so long. I'd already stumbled on the Wayland session wrapper issue because my services wouldn't start when I switched sessions via greetd when I was on Hyprland, but now with Niri this occurs right at startup. The services don't seem to start at the right time or lack the necessary context to run properly.

Brisingr05 commented 3 months ago

I just learned about uwsm (Universal Wayland Session Manager), which got added to Nixpkgs recently. Some links that might be of interest:

e-tho commented 2 months ago

The issue persists with the recently merged UWSM module.

╰─ sudo journalctl -xb | rg uwsm
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]: Preparing environment for niri...
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]: Exporting variables to systemd user manager:
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   DOCKER_HOST
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   EDITOR
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   GTK_PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   INFOPATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   LESSKEYIN_SYSTEM
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   LESSOPEN
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   LIBEXEC_PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   NIXPKGS_CONFIG
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   NIX_PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   NIX_PROFILES
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   NIX_USER_PROFILE_DIR
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   PAGER
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   QTWEBKIT_PLUGIN_PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   SSH_ASKPASS
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   TERM
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   TERMINFO_DIRS
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XCURSOR_PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_BACKEND
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_CONFIG_DIRS
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_CURRENT_DESKTOP
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_DATA_DIRS
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_MENU_PREFIX
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_SESSION_DESKTOP
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_SESSION_ID
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_SESSION_TYPE
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_VTNR
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   __ETC_PROFILE_DONE
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   __NIXOS_SET_ENVIRONMENT_DONE
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]: Variables marked for cleanup from systemd user manager on stop:
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   DISPLAY
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   DOCKER_HOST
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   EDITOR
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   GTK_PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   INFOPATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   LANG
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   LESSKEYIN_SYSTEM
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   LESSOPEN
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   LIBEXEC_PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   NIXPKGS_CONFIG
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   NIX_PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   NIX_PROFILES
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   NIX_USER_PROFILE_DIR
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   PAGER
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   QTWEBKIT_PLUGIN_PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   SSH_ASKPASS
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   TERM
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   TERMINFO_DIRS
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   WAYLAND_DISPLAY
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XCURSOR_PATH
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XCURSOR_SIZE
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XCURSOR_THEME
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_BACKEND
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_CONFIG_DIRS
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_CURRENT_DESKTOP
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_DATA_DIRS
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_MENU_PREFIX
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_SESSION_DESKTOP
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_SESSION_ID
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_SESSION_TYPE
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   XDG_VTNR
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   __ETC_PROFILE_DONE
Aug 29 19:13:44 nixos uwsm_env-preloader[2163]:   __NIXOS_SET_ENVIRONMENT_DONE
Aug 29 19:13:44 nixos uwsm_niri[2211]: Starting: /run/current-system/sw/bin/niri...
Aug 29 19:13:44 nixos uwsm_niri[2211]: 2024-08-29T17:13:44.461718Z  INFO niri: starting version unstable 2024-08-26 (commit 598b27f83c4d4dd72c5cfbd06ca60b12e2833429)
Aug 29 19:13:44 nixos uwsm_niri[2211]: 2024-08-29T17:13:44.469504Z DEBUG niri_config: loaded config from "/home/etho/.config/niri/config.kdl"
Aug 29 19:13:44 nixos uwsm_niri[2211]: 2024-08-29T17:13:44.944623Z  INFO niri::backend::tty: using as the render node: "/dev/dri/renderD128"
Aug 29 19:13:45 nixos uwsm_niri[2211]: 2024-08-29T17:13:45.069355Z DEBUG niri::backend::tty: device added: 57857 "/dev/dri/card1"
Aug 29 19:13:45 nixos uwsm_niri[2211]: 2024-08-29T17:13:45.380679Z DEBUG niri::backend::tty: this is the primary node
Aug 29 19:13:45 nixos uwsm_niri[2211]: 2024-08-29T17:13:45.380692Z DEBUG niri::backend::tty: this is the primary render node
Aug 29 19:13:45 nixos uwsm_niri[2211]: 2024-08-29T17:13:45.428766Z DEBUG niri::backend::tty: device changed: 57857
Aug 29 19:13:45 nixos uwsm_niri[2211]: 2024-08-29T17:13:45.433015Z DEBUG niri::backend::tty: connecting connector: DP-1
Aug 29 19:13:45 nixos uwsm_niri[2211]: 2024-08-29T17:13:45.433042Z DEBUG niri::backend::tty: picking mode: Mode { name: "2560x1440", clock: 645000, size: (2560, 1440), hsync: (2568, 2600, 2640), vsync: (1446, 1454, 1480), hskew: 0, vscan: 0, vrefresh: 165, mode_type: ModeTypeFlags(DRIVER) }
Aug 29 19:13:45 nixos uwsm_niri[2211]: 2024-08-29T17:13:45.433082Z DEBUG niri::backend::tty: set max bpc to 8
Aug 29 19:13:45 nixos uwsm_niri[2211]: 2024-08-29T17:13:45.440093Z DEBUG niri::niri: putting output DP-1 at x=0 y=0
Aug 29 19:13:45 nixos uwsm_niri[2211]: 2024-08-29T17:13:45.440148Z  INFO niri: listening on Wayland socket: wayland-1
Aug 29 19:13:45 nixos uwsm_niri[2211]: 2024-08-29T17:13:45.440154Z  INFO niri: IPC listening on: /run/user/1000/niri.wayland-1.2211.sock
Aug 29 19:14:50 nixos sudo[2897]:     etho : TTY=pts/0 ; PWD=/home/etho ; USER=root ; COMMAND=/run/current-system/sw/bin/journalctl -xb -u uwsm
╰─ systemctl --user status swayidle.service
○ swayidle.service - Idle manager for Wayland
     Loaded: loaded (/home/etho/.config/systemd/user/swayidle.service; enabled; preset: enabled)
     Active: inactive (dead)
  Condition: start condition unmet at Thu 2024-08-29 19:13:44 CEST; 4min 5s ago
             └─ ConditionEnvironment=WAYLAND_DISPLAY was not met
       Docs: man:swayidle(1)

Aug 29 19:13:44 nixos systemd[2039]: Idle manager for Wayland was skipped because of an unmet condition check (ConditionEnvironment=WAYLAND_DISPLAY).
Brisingr05 commented 2 months ago

I have yet to try UWSM, but my current workaround is to use the session target method. I used the Sway and Hyprland Home Manager modules as reference :

  1. Createniri-session.target:

    [Unit]
    After=graphical-session-pre.target
    Before=xdg-desktop-autostart.target
    BindsTo=graphical-session.target
    Description=niri compositor session
    Documentation=man:systemd.special(7)
    Wants=graphical-session-pre.target
    Wants=xdg-desktop-autostart.target
  2. Add the follwoing toconfig.kdl:

    spawn-at-startup "sh" "-c" "dbus-update-activation-environment --systemd --all && systemctl --user reset-failed && systemctl --user stop niri-session.target && systemctl --user start niri-session.target"
  3. Start niri with niri --session.

This is pretty much all I had to do to get user services working.

Pacman99 commented 2 months ago

I've been able to fix this with just pure systemd config and no spawn-at-startup lines or a niri-session.target.

I used this code in home-manager to switch to the upstream waybar systemd service in the waybar repo itself:

systemd.user.services.waybar = {
    Unit = {
      After = lib.mkForce [ "graphical-session.target" ];
      Requisite = [ "graphical-session.target" ];
    };
    Service = {
      ExecStartPost = "${pkgs.coreutils}/bin/sleep 2";
    };
  };

I also made a "tray.target" following the sway module in home-manager and set programs.waybar.systemd.target = "tray.target" and then set any service that has a system tray icon to start after both "graphical-session.target" and "tray.target".

A demo of this method is in this commit in my nix config repo: https://gitlab.com/coffeetables/lower/-/commit/cfc03d0b16b5c213959413097a7e3a950856af34. Theres also a commit after with some comments

Pacman99 commented 2 months ago

I think the reason that logout then login doesn't work is because graphical-session.target is still active when niri exits and its happening because of the niri-flake-polkit service. If I add this code to my nixos config, I'm no longer experiencing issues with systemd services not starting after logout then login:

systemd.user.services.niri-flake-polkit = {
    wants = lib.mkForce [];
    requisite = [ "graphical-session.target" ];
    partOf = [ "graphical-session.target" ];
  };

I think its because the niri-session script stops graphical-session.target by starting the niri-shutdown.target which conflicts with graphical-session.target, but niri-flake-polkit service has a dependency on graphical-session.target so systemd chooses to keep graphical-session.target running and stops niri-shutdown.target.

sodiboo commented 2 months ago

graphical-session.target is still active [...] because of the niri-flake-polkit service

WAIT WHAT. IT WAS MY FAULT ALL ALONG? I AM SO SORRY Y'ALL 😭

i will investigate this today and fix it if true. thank you @Pacman99 this seems like an entirely plausible diagnosis.

fyrk commented 2 months ago
systemd.user.services.niri-flake-polkit = {
    wants = lib.mkForce [];
    requisite = [ "graphical-session.target" ];
    partOf = [ "graphical-session.target" ];
  };

This seems to work for things like xdg-autostart, thank you!!!!! :tada: There's one thing I still need to change in my home-manager config, though, since Niri seems to only set WAYLAND_DISPLAY after graphical-session-pre.target and otherwise a service won't find the Wayland Display: If a service has After = [ "graphical-session-pre.target" ]; by default (for instance, waybar and swaync), this needs to be changed to "graphical-session.target".

Brisingr05 commented 2 months ago

I also made a "tray.target" following the sway module in home-manager and set programs.waybar.systemd.target = "tray.target" and then set any service that has a system tray icon to start after both "graphical-session.target" and "tray.target".

@Pacman99 Yeah I have this as well. @sodiboo I think tray.target should be added to niri-flake's Home Manager module, since this is what the HM modules of other compositors like Hyprland and Sway do.

I've been able to fix this with just pure systemd config and no spawn-at-startup lines or a niri-session.target.

I used this code in home-manager to switch to the upstream waybar systemd service in the waybar repo itself:

systemd.user.services.waybar = {
    Unit = {
      After = lib.mkForce [ "graphical-session.target" ];
      Requisite = [ "graphical-session.target" ];
    };
    Service = {
      ExecStartPost = "${pkgs.coreutils}/bin/sleep 2";
    };
  };

I also made a "tray.target" following the sway module in home-manager and set programs.waybar.systemd.target = "tray.target" and then set any service that has a system tray icon to start after both "graphical-session.target" and "tray.target".

A demo of this method is in this commit in my nix config repo: https://gitlab.com/coffeetables/lower/-/commit/cfc03d0b16b5c213959413097a7e3a950856af34. Theres also a commit after with some comments

I was actually doing this before I switched to the session target method. But instead of overriding After for every user service that required it, I preferred to follow what other HM modules were doing. In fact, Sway discourages starting itself as a user service. Although, the session script is slightly different from niri's and I don't know how relevant the problems mentioned in this old related issue are.

That said, I have no idea why some services started by HM modules start After graphical-session-pre.target rather than graphical-session.target, like their upstream service files (I cross-checked for the ones that are on my system). I should probably make an issue in HM's repo asking about this.

I think the reason that logout then login doesn't work is because graphical-session.target is still active when niri exits and its happening because of the niri-flake-polkit service. If I add this code to my nixos config, I'm no longer experiencing issues with systemd services not starting after logout then login:

systemd.user.services.niri-flake-polkit = {
    wants = lib.mkForce [];
    requisite = [ "graphical-session.target" ];
    partOf = [ "graphical-session.target" ];
  };

I think its because the niri-session script stops graphical-session.target by starting the niri-shutdown.target which conflicts with graphical-session.target, but niri-flake-polkit service has a dependency on graphical-session.target so systemd chooses to keep graphical-session.target running and stops niri-shutdown.target.

Hmm. I usually just wait about 8-10 secs after logging out before logging back in. I'm using polkit-gnome rather than the KDE one from the flake, but the code is almost the same. Only difference is WantedBy is graphical-session.target, not niri.service.

e-tho commented 2 months ago

That said, I have no idea why some services started by HM modules start After graphical-session-pre.target rather than graphical-session.target, like their upstream service files (I cross-checked for the ones that are on my system). I should probably make an issue in HM's repo asking about this.

Yeah, after discussing it here, it doesn't really make sense. All these services require the compositor to be running before they can start, and only graphical-session.target ensures that. Plus, the authors have set them up this way. I'm not sure why they were created like that in their HM module. I've already opened a PR to fix the swayidle module, but the other similar services will also need this patch.

Pacman99 commented 2 months ago

graphical-session.target is still active [...] because of the niri-flake-polkit service

WAIT WHAT. IT WAS MY FAULT ALL ALONG? I AM SO SORRY Y'ALL 😭

i will investigate this today and fix it if true. thank you @Pacman99 this seems like an entirely plausible diagnosis.

I mean I think your service is written well and as @Brisingr05 pointed out it's similar to the systemd service recommended for polkit-gnome. I'm not sure why systemd chooses to keep graphical-session.target up, because in the manual it doesn't mention that behavior and only says that conflicts might not work when one service "requires" the conflicting service. Either way I guess there's no reason for niri-flake-polkit to have a Wants dependency on graphical-session.target since no one is likely to start it manually outside a compositor.

sodiboo commented 2 months ago

I'm not sure why systemd chooses to keep graphical-session.target

I guess it's because the polkit service doesn't die when niri shuts down, and other than this it basically runs as "part of" graphical-session.target, in a similar way to niri.

Pacman99 commented 2 months ago

I was actually doing this before I switched to the session target method. But instead of overriding After for every user service that required it, I preferred to follow what other HM modules were doing. In fact, Sway discourages starting itself as a user service. Although, the session script is slightly different from niri's and I don't know how relevant the problems mentioned in this old related issue are.

Even when I used the session target method encouraged by home-manager I still had to override After for every service so it ended up being more work overall. AFAICT the only advantage of that method is if you want gnome and niri/sway/hyprland to be available at login together and not have waybar and things start with gnome. But I believe UWSM's solution of adding ExecCondition=systemd-xdg-desktop-condition "niri:sway:hyprland" "" is better for that as you don't need to to make a new target for each compositior. And I think that works even without using UWSM, but I haven't specifically tried it.

sodiboo commented 2 months ago

WAIT WHAT. IT WAS MY FAULT ALL ALONG? I AM SO SORRY Y'ALL 😭

Okay, so yeah i've reproduced the same issue described. After closing niri, graphical-session.target is still active. This new commit addresses this by making the niri-flake-polkit service run as partOf = ["graphical-session.target"]; instead of wanting it.

https://github.com/sodiboo/niri-flake/commit/fd00de202cc0287f7b34c237b8585e67fe7b85f7

This solves a lot of the jank i have, and i think i was able to remove all special casing from my config necessary to get waybar working. My swaybg unit also no longer needs to reference niri, and works robustly when it is PartOf and WantedBy the graphical-session.target.

I am so sorry for having this be persistently broken for at least 7 months. Hopefully everyone's issues are resolved, or at least mediated, by this new change. Thank you @Pacman99

ocfox commented 1 month ago

since Niri seems to only set WAYLAND_DISPLAY after graphical-session-pre.target and otherwise a service won't find the Wayland Display.

How to solve this, home-manager swayidle failed start.

Brisingr05 commented 1 month ago

since Niri seems to only set WAYLAND_DISPLAY after graphical-session-pre.target and otherwise a service won't find the Wayland Display.

How to solve this, home-manager swayidle failed start.

You need to override the swayidle service in Home Manager:

systemd.user.swayidle.Unit.After = [ "graphical-session.target" ];
sodiboo commented 1 month ago

You need to override the swayidle service in Home Manager:

systemd.user.swayidle.Unit.After = [ "graphical-session.target" ];

this shouldn't be necessary :neocat_anxiety: it's already WantedBy and PartOf the graphical-session.target.

(if this workaround fixes it on your setup, then great do it and just appreciate it working, but there is definitely something wrong because it really shouldn't be necessary. something more fundamental should be fixed in niri-flake and/or niri)

soulsoiledit commented 1 month ago

After 318b1ef1b47bc30dddd0b14b0a8a2093039e275a, most of my services don't need me to define After= in order to start properly. They also restart properly after logging out and back in again. The notable exceptions were anything involving the system tray (udiskie, blueman-applet, nm-applet, etc). This seems be because they rely on both tray.target (which definitely should be defined in the module), and because they start after graphical-session-pre.target. The outlier to those was wlsunset, and I'm not really sure why it's still failing.

Pacman99 commented 1 month ago

I'm surprised the commit made it so services don't need to have After=graphical-session.target. I don't see why systemd would have any reason to start them after niri since all of them are started when graphical-session.target is started and they are all started before graphical-session.target is reached.

Brisingr05 commented 1 month ago

this shouldn't be necessary :neocat_anxiety: it's already WantedBy and PartOf the graphical-session.target.

(if this workaround fixes it on your setup, then great do it and just appreciate it working, but there is definitely something wrong because it really shouldn't be necessary. something more fundamental should be fixed in niri-flake and/or niri)

According to the docs, After= is needed for correct ordering of dependencies. Also see @Vladimir-csp's comments here. PartOf=, on the other hand, is "limited to stopping and restarting of units.". Take a look at the upstream service files for hypridle, waybar, swaync, mako, fnott and wob. They all have After=graphical-session.target. So I don't think there's any issue with niri upstream or in this flake. Although, the recent changes to the KDE polkit were a good decision; After=graphical-session.target makes sure the polkit service starts after the graphical environment (graphical-session.target) has fully started, and PartOf=graphical-session.target makes sure that the polkit service stops when graphical-session.target stops. Moreover, it's Home Manager's choice to configure certain services with After=graphical-session-pre.target that seem to be causing issues. You're less likely to have issues with user services (even with incorrect ordering) when using the HM modules of Hyprland or SwayWM, because they use the session target method (see my earlier comment for more info). At some point I gotta make an issue in HM's repo, asking about the reasoning behind After=graphical-session-pre.target, because according to the docs "this target contains services which set up the environment or global configuration of a graphical session", which doesn't make sense for programs/services that need to be started after the graphical session has started.

After 318b1ef, most of my services don't need me to define After= in order to start properly. They also restart properly after logging out and back in again. The notable exceptions were anything involving the system tray (udiskie, blueman-applet, nm-applet, etc). This seems be because they rely on both tray.target (which definitely should be defined in the module), and because they start after graphical-session-pre.target. The outlier to those was wlsunset, and I'm not really sure why it's still failing.

I'm surprised the commit made it so services don't need to have After=graphical-session.target. I don't see why systemd would have any reason to start them after niri since all of them are started when graphical-session.target is started and they are all started before graphical-session.target is reached.

I decided to do some testing without any After= modifications and starting niri with niri-session (so no external session manager like UWSM). I also noticed some services starting without After=graphical-session.target. Swayidle and nm-applet didn't start (errors were ConditionEnvironment=WAYLAND_DISPLAY was not met andcannot open display respectively), which makes sense because of incorrect ordering. I hadn't tested Waybar yet, but Ironbar was also failing - upstream service isn't great either; I had to set WantedBy=graphical-session.target for it to even attempt to start. But gammastep worked, even though it had After=graphical-session-pre.target. When I ran systemctl --user status gammastep.service, I saw this: gammastep.service: Scheduled restart job, restart counter is at 1.. Turns out, it did fail; it just restarted in 3 secs because of Restart=on-failure and RestartSec=3. I then tried this with the polkit service by removing After=. Same result: it fails and restarts. Same result when I tried this with Ironbar, but something else happened - nm-applet and swayidle started working as well 🙃. At this point I had also enabled Waybar, which failed to start on its own, but did start when Ironbar restarted. My knowledge of systemd is very limited, so I have no idea why this was happening. But the Ironbar thing is kinda irrelevant.

tl;dr:

soulsoiledit commented 1 month ago

Turns out, it did fail; it just restarted in 3 secs because of Restart=on-failure and RestartSec=3

After checking logs, it seems like that happened in my case as well. It's weird that the units completely failed before but manage to get a successful startup now though.

EDIT: https://github.com/nix-community/home-manager/pull/5785 would resolve the ordering issue.

Pacman99 commented 1 month ago

Okay the services restarting and succeeding makes sense. This definitely needs to be properly fixed in the home manager side. It might be good to add something in the Readme here about the issue and how to workaround it.

tray.target can be useful for applications that only show their system tray icon if a tray is available when they start up. I binded waybar to tray.target and added ExecStartPost=sleep 1 to ensure systemd only considered tray.target reached after waybar had finished starting up. Then I made systemd services for my startup apps and had them depend on and start after tray.target.