From d26393d60cc40565ce641c14402857dd30f40183 Mon Sep 17 00:00:00 2001 From: K900 Date: Thu, 25 May 2023 14:56:49 +0300 Subject: [PATCH] nixos/x11/display-managers: don't touch graphical-session.target in xsession-wrapper if the desktop knows how to handle it This is not correct and will in fact break things because they try to run before the target is reached. Ideally we'd get rid of it entirely, but WM users rely on this behavior, so allowlist some desktops to get the sane behavior, and fake the session for the rest until upstreams/NixOS modules catch up. --- .../services/x11/display-managers/default.nix | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index 995ecd231c43..1f08ded7c96f 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/nixos/modules/services/x11/display-managers/default.nix @@ -27,6 +27,30 @@ let Xft.hintstyle: ${fontconfig.hinting.style} ''; + # FIXME: this is an ugly hack. + # Some sessions (read: most WMs) don't activate systemd's `graphical-session.target`. + # Other sessions (read: most non-WMs) expect `graphical-session.target` to be reached + # when the entire session is actually ready. We used to just unconditionally force + # `graphical-session.target` to be activated in the session wrapper so things like + # xdg-autostart-generator work on sessions that are wrong, but this broke sessions + # that do things right. So, preserve this behavior (with some extra steps) by matching + # on XDG_CURRENT_DESKTOP and deliberately ignoring sessions we know can do the right thing. + fakeSession = action: '' + session_is_systemd_aware=$( + IFS=: + for i in $XDG_CURRENT_DESKTOP; do + case $i in + KDE|GNOME|X-NIXOS-SYSTEMD-AWARE) echo "1"; exit; ;; + *) ;; + esac + done + ) + + if [ -z "$session_is_systemd_aware" ]; then + /run/current-system/systemd/bin/systemctl --user ${action} nixos-fake-graphical-session.target + fi + ''; + # file provided by services.xserver.displayManager.sessionData.wrapper xsessionWrapper = pkgs.writeScript "xsession-wrapper" '' @@ -90,8 +114,7 @@ let ${cfg.displayManager.sessionCommands} - # Start systemd user services for graphical sessions - /run/current-system/systemd/bin/systemctl --user start graphical-session.target + ${fakeSession "start"} # Allow the user to setup a custom session type. if test -x ~/.xsession; then @@ -417,10 +440,10 @@ in "XDG_SESSION_ID" ]; - systemd.user.targets.graphical-session = { + systemd.user.targets.nixos-fake-graphical-session = { unitConfig = { - RefuseManualStart = false; - StopWhenUnneeded = false; + Description = "Fake graphical-session target for non-systemd-aware sessions"; + BindsTo = "graphical-session.target"; }; }; @@ -451,7 +474,7 @@ in test -n "$waitPID" && wait "$waitPID" - /run/current-system/systemd/bin/systemctl --user stop graphical-session.target + ${fakeSession "stop"} exit 0 '';