Commit graph

6 commits

Author SHA1 Message Date
779ff3d495 Stop motion wallpaper when the Omarchy theme changes
mpvpaper kept running over the new theme's static wallpaper because
nothing was watching the omarchy-theme symlink. Add a small sibling
script that polls ~/.config/omarchy/current/background and, when the
target changes, runs `motion-wallpaper-toggle stop` — which tears down
mpvpaper and respawns swaybg with the new symlink target so the new
theme's bg becomes visible.

- motion-wallpaper-theme-watcher: polls readlink every 2s, exits silently
  on non-Omarchy systems where the symlink doesn't exist.
- toggle: spawn alongside the auto-pause watcher; kill alongside it.
- wallpaper.sh: install the new binary.
2026-04-25 09:04:08 +01:00
9e201769c9 Cross-check HIS against hyprctl instances (dir can linger)
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.
2026-04-23 22:52:51 +01:00
154bcc85d4 Also recover when HYPRLAND_INSTANCE_SIGNATURE is stale
Walker's env can carry a stale HIS across Hyprland restarts — the variable
points at a signature whose socket dir no longer exists, so hyprctl dumps
a plain-text "not running" error to stdout and the TUI silently bails.

Validate HIS against `$XDG_RUNTIME_DIR/hypr/$HIS/` and fall through to the
`hyprctl instances` recovery path when the directory is missing, not only
when HIS is unset. Same detection added to the watcher.
2026-04-23 22:50:14 +01:00
c0c5758bfe Recover HYPRLAND_INSTANCE_SIGNATURE when launcher env is stripped
Running the TUI from XDG launchers (and some cron/ssh contexts) can leave
HYPRLAND_INSTANCE_SIGNATURE unset. hyprctl then prints a plain-text error
to stdout and exits 0, which made jq emit "Invalid numeric literal" to the
terminal before the tui_err message.

- ensure_hyprland_env: detect the running instance via `hyprctl instances`
  and export HIS before the first hyprctl call.
- get_monitors: validate JSON with `jq -e` before parsing, fall back to
  text-mode `hyprctl monitors` if the JSON is broken.
- pick_target: surface a clear error when HIS can't be recovered.
- watcher: same recovery path so auto-pause still works when launched
  without HIS in env.
2026-04-23 22:47:02 +01:00
2ce38ce9eb Harden stop path, autostart, and state file
Bug-check pass on top of the v2 rewrite. Five real issues fixed:

* autostart_enable used to return the exit code of the trailing `log`
  call, so a failing `systemctl --user enable` was silently reported
  as success. Now returns 1 with a tui_err on real failure.

* save_state wrote directly to STATE_FILE; a crash mid-write would
  leave a truncated file that load_state would partially parse.
  Switched to an atomic tmp + mv -f pattern.

* load_state used `source "$STATE_FILE"` which is arbitrary code
  execution if a video path ever contained shell metacharacters.
  Replaced with a read-based KEY=VALUE parser that only honours
  LAST_VIDEO / LAST_TARGET / LAST_DIR.

* stop_mpvpaper can be called twice in quick succession (TUI stop
  immediately followed by systemd's ExecStop). Wrapped the whole
  body in a `flock -n` on $STATE_DIR/.stop.lock so the second caller
  no-ops instead of racing against the first.

* Watcher `cleanup` trap used `[ -n VAR ] && kill`, which
  short-circuits to non-zero when VAR is unset and aborts the trap
  before `exit 0` under set -e. Restructured to a proper if/|| true.
2026-04-23 20:52:41 +01:00
f31ff2b152 v2: gum TUI, autostart, auto-pause watcher, Omarchy fixes
Major rewrite of the runtime so the entry point is a proper gum TUI
instead of zenity dialogs, plus a handful of correctness fixes that
make it work on real Omarchy setups.

Runtime (motion-wallpaper-toggle, extracted from the installer heredoc):
  * Full gum TUI: status header, monitor picker (with All monitors),
    library / filesystem pickers, change-video, autostart toggle.
  * State file at ~/.config/motion-wallpaper/state remembers last
    video, target monitor, and last-used directory so Browse reopens
    where the user was.
  * Actions: toggle | start | stop | change | status.

Autostart:
  * Ships a systemd user unit (motion-wallpaper.service).
  * First fresh start prompts the user via gum confirm to enable it.
  * Running-state menu offers a Turn autostart ON/OFF entry.
  * Header shows the current autostart state.

Auto-pause:
  * mpvpaper's -p is unreliable on Hyprland 0.54.x, so a small
    motion-wallpaper-watcher subscribes to Hyprland's socket2 and
    toggles mpv pause/resume via --input-ipc-server on fullscreen
    enter/exit. Started/stopped alongside mpvpaper.

Omarchy compatibility:
  * Stop path now respawns swaybg pointed at
    ~/.config/omarchy/current/background via setsid uwsm-app (the way
    Omarchy autostarts it), instead of execing hyprpaper which isn't
    present. Falls back to hyprpaper on non-Omarchy Hyprland setups.
  * mpvpaper is launched under setsid uwsm-app so it survives the
    Walker-spawned terminal closing.

Install / UX:
  * Installer only invokes sudo/yay when packages are actually
    missing, so reinstall is quiet.
  * Dropped zenity; added gum + socat + libnotify.
  * Custom SVG icon in the hicolor theme so Walker shows a proper
    tile. Installer restarts elephant.service so the new entry/icon
    appear without logout.
  * .desktop flipped to Terminal=true so launchers spawn a terminal
    for the TUI.
  * Watcher lookup falls back to the script's own dir when PATH is
    minimal (launcher-spawned terminals).

Bug fixes:
  * Monitor picker was sending row-major data to zenity as one cell;
    fixed (kept the correct form for the new gum picker).
  * load_state / action_status no longer leak a non-zero exit code
    from trailing test expressions.
  * Stop path cleans up stray hyprpaper that would otherwise win the
    background layer.
2026-04-23 20:33:02 +01:00