From 709b80e65c9717e09442833380bdef23e830d15e Mon Sep 17 00:00:00 2001 From: nevaforget <> Date: Wed, 9 Sep 2026 15:54:03 +0200 Subject: [PATCH] fix(desktop): keep launcher apps out of the bar's cgroup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quickshell has no scope support of its own, so apps started from its launcher inherited the cgroup of quickshell.service and systemd killed them along with the unit on every restart — a rebuild that rewrites the unit was enough, and Librewolf counted each one as a crash until it refused to restore the session. app2unit is the start prefix the QML now uses; see moonarch's LauncherPopout.qml. The unit also gained a start limit. After a rebuild sent niri SIGTERM, graphical-session.target stayed up while the Wayland socket was gone, so Restart=on-failure spun 32 times in two minutes against a dead display. Three tries per 30s ends that; the window slides, so a single crash after a normal run still gets its restart. --- flake.lock | 8 ++++---- modules/desktop.nix | 11 +++++++++++ modules/services.nix | 12 ++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/flake.lock b/flake.lock index 98a6403..24e015e 100644 --- a/flake.lock +++ b/flake.lock @@ -24,11 +24,11 @@ "moonarch": { "flake": false, "locked": { - "lastModified": 1788955787, - "narHash": "sha256-VII5Od3i1YyHqIWJgDb2El58Xf2XgCdcnfRNzmz0ueg=", + "lastModified": 1788961983, + "narHash": "sha256-ndUyq3X3E5vVdUflbCxdd2c+CBlXcNgn0rc5qiovCUM=", "ref": "refs/heads/main", - "rev": "7a24cdb6ae1831ffe74c54f1bce1d3538147284f", - "revCount": 178, + "rev": "ba3745603cd01508669a70e56527e3d471a0d5f6", + "revCount": 179, "type": "git", "url": "https://gitea.moonarch.de/nevaforget/moonarch.git" }, diff --git a/modules/desktop.nix b/modules/desktop.nix index e11087a..f1bf596 100644 --- a/modules/desktop.nix +++ b/modules/desktop.nix @@ -305,6 +305,17 @@ in cliphist wl-clipboard + # The launcher's start prefix, and why the launcher needs one: Quickshell + # spawns applications as its own children, and a child inherits its + # parent's cgroup, so everything started from the launcher lands inside + # quickshell.service — which systemd kills whole on every restart of the + # unit (KillMode=control-group is the default). A crash of the bar took the + # open browser with it, and Librewolf counted each one as a crash until it + # stopped restoring the session at all. app2unit wraps systemd-run to put + # each application in its own transient app-*.scope, the same shape niri + # gives the windows it spawns itself. + app2unit + # Display and wallpaper wlsunset nwg-look diff --git a/modules/services.nix b/modules/services.nix index 3020f67..4add3b2 100644 --- a/modules/services.nix +++ b/modules/services.nix @@ -159,6 +159,18 @@ in # this file. As a spawn-at-startup it inherited the session PATH; the unit # gets the same set rather than a list that goes stale on the next widget. path = [ config.system.path ]; + # Restart=on-failure alone spun 32 times through a dead Wayland socket after + # a rebuild had sent niri SIGTERM: graphical-session-pre.target went down, + # graphical-session.target stayed up, so the unit was still wanted and every + # attempt died on "no Qt platform plugin could be initialized". Quickshell + # refuses a relaunch itself ("crashed within 10 seconds"), but systemd never + # reached the default limit of 5 starts per 10s at a 3s delay. Three tries + # per 30s ends it after ~9s. The window slides, so a single crash after a + # normal run still gets its restart — the point of running this as a unit. + unitConfig = { + StartLimitIntervalSec = 30; + StartLimitBurst = 3; + }; serviceConfig = { Type = "simple"; ExecStart = "${lib.getExe pkgs.quickshell} -c moonarch";