From c2281dbc6181a2fa2eff3b9c66539854905b6e52 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Thu, 18 Jun 2026 19:00:39 +0100 Subject: [PATCH] fix(waybar): launch from exec-once, not a systemd user service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Waybar vanished after a logout→login (no reboot): the bar's systemd user service landed in `failed`. HM's Hyprland integration cycles hyprland-session.target on every launch (exec-once stop && start), which re-pulls WantedBy units — including waybar.service — very early, before Hyprland's IPC socket is ready. Waybar's hyprland/workspaces & window modules can't connect, so it exits non-zero and is never retried. A cold boot's extra latency hid the race, so it only bit on warm relogins. The non-IPC session services (swaync/hypridle/hyprsunset) survive the same cycling fine, which is why night-light kept working. Launch waybar from Hyprland's own exec-once instead (systemd.enable = false). exec-once entries are dispatched once the compositor is up, so the IPC socket is ready — the same reliable pattern awww-daemon, the wallpaper sync and the keyboard watcher already use across relogins. Since the unit no longer exists to be restarted on a home-manager switch, nudge the running bar to re-read its rebuilt config/style with SIGUSR2 from nomarchy-theme-sync so theme switches still reapply the bar live. Found on the Latitude 5410 hardware sweep (systemctl --user status showed waybar.service loaded/failed; manual start worked). Co-Authored-By: Claude Opus 4.8 --- modules/home/hyprland.nix | 8 +++++++- modules/home/waybar.nix | 9 ++++++++- pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py | 5 +++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/modules/home/hyprland.nix b/modules/home/hyprland.nix index 75993fa..c908194 100644 --- a/modules/home/hyprland.nix +++ b/modules/home/hyprland.nix @@ -152,7 +152,13 @@ in # Paint the wallpaper as soon as the session is up (waits for # the daemon internally). "nomarchy-theme-sync wallpaper" - ] ++ lib.optional kbAutoSwitch "${keyboardWatch}/bin/nomarchy-keyboard-watch"; + # Waybar is launched here rather than as a systemd user service: bound + # to graphical-session.target the unit raced Hyprland's IPC on relogin + # and landed in `failed`; exec-once only fires once the compositor is + # up. Reloaded on theme switch via SIGUSR2 (nomarchy-theme-sync). See + # waybar.nix. + ] ++ lib.optional config.nomarchy.waybar.enable "waybar" + ++ lib.optional kbAutoSwitch "${keyboardWatch}/bin/nomarchy-keyboard-watch"; # ── Theme-driven look ────────────────────────────────────────── # These flow from theme-state.json and stay at NORMAL priority: diff --git a/modules/home/waybar.nix b/modules/home/waybar.nix index 98eb5c3..aba5ffa 100644 --- a/modules/home/waybar.nix +++ b/modules/home/waybar.nix @@ -228,7 +228,14 @@ in { programs.waybar = lib.mkIf config.nomarchy.waybar.enable { enable = true; - systemd.enable = true; # started/stopped with graphical-session.target + # Launched from Hyprland's exec-once (hyprland.nix), NOT a systemd user + # service. Bound to graphical-session.target the unit raced Hyprland's IPC + # on a warm relogin — it started before the socket was up, exited, landed + # in `failed`, and was never retried, so the bar vanished. exec-once only + # fires once Hyprland is up, dodging the race; theme switches reload the + # running bar via SIGUSR2 (nomarchy-theme-sync). No uwsm here to manage the + # session target, so we don't depend on its lifecycle. + systemd.enable = false; # mkDefault so downstream can replace the whole bar config/style with # a plain home.nix assignment. For per-theme identity, prefer the diff --git a/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py b/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py index 16c1e54..7292870 100644 --- a/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py +++ b/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py @@ -171,6 +171,11 @@ def run_switch() -> None: notify("Theme rebuild FAILED — see terminal / journal", urgency="critical") die("rebuild failed (state file already updated; fix and re-run)") notify("Theme applied ✓") + # Waybar runs from Hyprland's exec-once (not a systemd unit HM would restart + # on switch), so nudge the running bar to re-read its freshly rebuilt + # config/style. SIGUSR2 = reload; harmless no-op if waybar isn't running. + if shutil.which("pkill"): + subprocess.run(["pkill", "--signal", "SIGUSR2", "-x", "waybar"], check=False) # ─── Theme assets (wallpapers) ────────────────────────────────────────────