From 9e201769c9dcf6695c00152093249993bf9f5569 Mon Sep 17 00:00:00 2001 From: 28allday Date: Thu, 23 Apr 2026 22:52:51 +0100 Subject: [PATCH] Cross-check HIS against hyprctl instances (dir can linger) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous check trusted $XDG_RUNTIME_DIR/hypr/$HIS/ existing, but the directory and its socket files can remain on disk after the session dies. On a real run the stale signature still had a dir, so the guard passed and hyprctl silently failed again. ensure_hyprland_env now queries `hyprctl instances` — the source of truth for live sessions — and rewrites HIS if ours isn't in the list. Watcher mirrors the same logic. Also: drop the outdated "zenity" mention from the installer header. --- motion-wallpaper-toggle | 41 ++++++++++++++++++++++------------------ motion-wallpaper-watcher | 22 ++++++++++----------- wallpaper.sh | 9 +++++---- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/motion-wallpaper-toggle b/motion-wallpaper-toggle index c3d2e09..113bf11 100644 --- a/motion-wallpaper-toggle +++ b/motion-wallpaper-toggle @@ -182,28 +182,33 @@ show_header() { # ===== selection ============================================================== ensure_hyprland_env() { - # The TUI can be launched from contexts whose env doesn't carry a valid - # HYPRLAND_INSTANCE_SIGNATURE. Two failure modes: - # 1) HIS unset (fresh login shell from a non-graphical context) - # 2) HIS set but STALE — points to a previous Hyprland session whose - # socket no longer exists (seen when Walker's env carries the - # signature from an earlier login). The second case is silent but - # equally broken: hyprctl dumps a plain-text error on stdout. - # `hyprctl instances` always reports the *live* signatures, so recover - # from that. Leave HIS unchanged if we can't find a live instance. + # The TUI can be launched from contexts whose HYPRLAND_INSTANCE_SIGNATURE + # isn't usable. Three failure modes, all silent: + # 1) HIS unset (fresh login shell, cron, ssh). + # 2) HIS set but points to a dead session — the `hypr//` directory + # and its socket files can linger on disk after the Hyprland process + # exits, so a dir-exists check is not enough. + # 3) Walker's env retained an old HIS across a Hyprland restart. + # `hyprctl instances` is the source of truth: it only reports live + # instances. Always cross-check against it and rewrite HIS if ours isn't + # in the list. local his="${HYPRLAND_INSTANCE_SIGNATURE:-}" - if [ -n "$his" ] && [ -d "$RUNTIME_DIR/hypr/$his" ]; then + local live + live="$(hyprctl instances 2>/dev/null | awk '/^instance /{sub(/:$/,"",$2); print $2}')" + if [ -z "$live" ]; then + # No live Hyprland — nothing we can do, let the caller surface an error. + return 0 + fi + if [ -n "$his" ] && printf '%s\n' "$live" | grep -qxF "$his"; then return 0 fi local sig - sig="$(hyprctl instances 2>/dev/null | awk '/^instance /{sub(/:$/,"",$2); print $2; exit}')" - if [ -n "$sig" ] && [ "$sig" != "$his" ]; then - export HYPRLAND_INSTANCE_SIGNATURE="$sig" - if [ -n "$his" ]; then - log "replaced stale HYPRLAND_INSTANCE_SIGNATURE ($his → $sig)" - else - log "recovered HYPRLAND_INSTANCE_SIGNATURE=$sig from hyprctl instances" - fi + sig="$(printf '%s\n' "$live" | head -n 1)" + export HYPRLAND_INSTANCE_SIGNATURE="$sig" + if [ -n "$his" ]; then + log "replaced stale HYPRLAND_INSTANCE_SIGNATURE ($his → $sig)" + else + log "recovered HYPRLAND_INSTANCE_SIGNATURE=$sig from hyprctl instances" fi } diff --git a/motion-wallpaper-watcher b/motion-wallpaper-watcher index f9d17eb..c61b4d6 100644 --- a/motion-wallpaper-watcher +++ b/motion-wallpaper-watcher @@ -21,17 +21,17 @@ log() { } his="${HYPRLAND_INSTANCE_SIGNATURE:-}" -if [ -z "$his" ] || [ ! -d "$RUNTIME_DIR/hypr/$his" ]; then - # HIS is missing or stale (points to a dead session). Recover from the - # live signature reported by `hyprctl instances`. - sig="$(hyprctl instances 2>/dev/null | awk '/^instance /{sub(/:$/,"",$2); print $2; exit}')" - if [ -n "$sig" ]; then - export HYPRLAND_INSTANCE_SIGNATURE="$sig" - log "using HYPRLAND_INSTANCE_SIGNATURE=$sig (was: ${his:-unset})" - else - log "HYPRLAND_INSTANCE_SIGNATURE not usable and no live instance found — exiting" - exit 0 - fi +# Cross-check against `hyprctl instances` — the socket dir alone can linger +# on disk after a session dies, so a dir-exists check isn't reliable. +live="$(hyprctl instances 2>/dev/null | awk '/^instance /{sub(/:$/,"",$2); print $2}')" +if [ -z "$live" ]; then + log "no live Hyprland instance reported by hyprctl — exiting" + exit 0 +fi +if [ -z "$his" ] || ! printf '%s\n' "$live" | grep -qxF "$his"; then + sig="$(printf '%s\n' "$live" | head -n 1)" + export HYPRLAND_INSTANCE_SIGNATURE="$sig" + log "using HYPRLAND_INSTANCE_SIGNATURE=$sig (was: ${his:-unset})" fi HYPR_SOCK="$RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" diff --git a/wallpaper.sh b/wallpaper.sh index e91c8c5..9c6ff5f 100644 --- a/wallpaper.sh +++ b/wallpaper.sh @@ -3,14 +3,15 @@ # Motion Wallpaper Installer for Omarchy / Hyprland # # Installs: -# ~/.local/bin/motion-wallpaper-toggle runtime script +# ~/.local/bin/motion-wallpaper-toggle runtime TUI +# ~/.local/bin/motion-wallpaper-watcher auto-pause watcher # ~/.local/share/applications/motion-wallpaper-toggle.desktop app entry -# ~/.config/systemd/user/motion-wallpaper.service optional autostart unit +# ~/.local/share/icons/hicolor/scalable/apps/motion-wallpaper.svg icon +# ~/.config/systemd/user/motion-wallpaper.service optional autostart unit # # Dependencies: -# mpv, jq, zenity (pacman) +# mpv, jq, gum, socat, libnotify (pacman) # mpvpaper (AUR, via yay or paru) -# libnotify (pacman) — optional, for notify-send # ============================================================================== set -euo pipefail