Commit graph

15 commits

Author SHA1 Message Date
f96246a90d README: catch up with theme-watcher, floating TUI, theme-aware UI
Doc drift since 48dd9b2:

- Intro now mentions the theme-watcher and that the TUI follows the
  active Omarchy theme + launches as a floating window.
- Files Created table adds motion-wallpaper-theme-watcher and the
  .desktop note now reflects xdg-terminal-exec --app-id=TUI.float
  instead of the old Terminal=true line.
- "From App Launcher" describes the floating-window behaviour and the
  colors.toml theme integration.
- "Toggle — already running" notes that Change video also picks the
  target monitor and that the menu loops back after each action; saved
  targets are validated against hyprctl monitors with All-monitors
  fallback if the saved monitor is gone.
- New "Theme change" subsection in How It Works, plus a note on the
  HYPRLAND_INSTANCE_SIGNATURE self-recovery in the auto-pause section.
- Uninstall removes motion-wallpaper-theme-watcher.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 15:46:28 +01:00
Gavin Nugent
601dd8c396 Loop TUI, multi-monitor, validate saved target
- Multi-monitor: keep theme background on non-target outputs via swaybg -o
- TUI loops back to main menu after every action; only Cancel/Esc exits
- Change video now also lets you pick the monitor
- Validate saved target against live hyprctl monitors; fall back to "*" if
  the monitor was unplugged between sessions
- Restore terminal state on exit (cnorm/rmcup) so gum can't leave the
  floating window with a frozen cursor
- show_panel writes to stderr so command-substitution callers (pick_target,
  pick_video, browse_filesystem) can't capture panel bytes into their result
- Center the panel + indent --header label and gum cursor to match
- Align colons in the status panel by left-padding labels
- Handle 0-monitor edge case in pick_target with a clear error
- Wrap save_state's umask 077 in a subshell so it doesn't leak

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 15:29:24 +01:00
Gavin Nugent
ee9d894ad9 TUI: float from Walker, follow Omarchy theme, center the layout
Launcher
  - .desktop now wraps the toggle in `xdg-terminal-exec --app-id=TUI.float`
    so Hyprland's existing floating-window rule treats it like btop / impala
    instead of opening a tiled fullscreen terminal.

Theme integration
  - Read ~/.config/omarchy/current/theme/colors.toml at startup; map
    accent/color1/color2/color8 → COLOR_ACCENT/ERROR/OK/MUTED. Catppuccin
    fallback if the file is missing.
  - Push the theme into gum's own widget chrome (cursor, selected row,
    headers, prompts, confirm) via GUM_* env vars so the menu cursor and
    highlight follow the active theme instead of gum's pink defaults.

Centered layout
  - Compute panel width / margin / top-pad from `tput cols` + `tput lines`.
  - Status panel rendered with --margin to center horizontally; title
    centered inside the box.
  - GUM_CHOOSE_CURSOR padded with PANEL_INDENT so menu rows line up with
    the panel's left edge.
  - prompt_header indents the per-prompt label and appends a centered,
    muted nav hint; gum's flush-left help footer suppressed via
    GUM_CHOOSE_SHOW_HELP=false (also filter / file).
  - center_screen() clears + pads before each gum prompt so the UI sits
    vertically centered on every navigation step.

Stopped-state menu
  - Replaced the "panel flashes then drops into file picker" flow with a
    gum-choose menu first: Start with <last video> / Pick a video and
    start / Turn autostart ON|OFF / Cancel. Status panel stays visible.

$HOME-confined browser
  - Replaced gum file (alt-screen, can navigate above $HOME via its
    built-in up key) with a gum-choose-driven browser. The "Up one
    folder" entry is omitted when at $HOME, so escape is structurally
    impossible. Lists folders first, then video files; remembers
    LAST_DIR; bounces back to $HOME on empty leaves and bails if even
    $HOME has no entries (instead of looping).

Centralized strings
  - All ~50 user-facing labels live in a single TXT_* block at the top
    of the script, grouped by purpose (header / menu / confirm /
    success / error / notification). Format strings use printf %s.

Robustness
  - Clamp PANEL_WIDTH ≤ TERM_COLS for narrow floating windows.
  - Empty-dir warning rendered with the same horizontal margin as
    everything else.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 13:45:08 +01:00
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
48dd9b2f0a README: catch up with watcher, autostart prompts, state parsing
Doc drift from the last two commits:

* Intro mentioned "--auto-pause" — replaced with the external watcher,
  so rewrite to describe that instead.
* Added socat to the deps table and the new motion-wallpaper-watcher
  binary + SVG icon to the Files Created table.
* State file description updated to include LAST_DIR; mentions the
  atomic write + safe KEY=VALUE parser.
* Autostart section replaced with the TUI-first flow (first-run
  prompt, menu toggle, stop-offers-disable, disable-offers-stop),
  with systemctl as an alternative.
* How It Works expanded with the setsid + uwsm-app spawn, the flock
  on the stop path, and a new "Auto-pause (the watcher)" subsection
  describing the Hyprland socket2 + mpv IPC bridge.
* Added a troubleshooting entry for auto-pause not firing
  (fullscreen vs full-width, watcher log check).
* Uninstall removes the new watcher binary; package remove line
  updated to the real deps (was still listing zenity).
2026-04-23 20:54:58 +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
nosignal
f25cef8780 Update links to Forgejo 2026-04-07 00:53:05 +01:00
3206f7b22f
Add video demo link and thumbnail to README
Added a video thumbnail and link to README.
2026-03-28 15:34:58 +00:00
4c2b5052e3 Add detailed comments to script and comprehensive README
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:29:19 +00:00
a46b21a763 Fix keybind conflict and wallpaper daemon handling
- Changed suggested keybind from SUPER+W (conflicts with Close window
  in Omarchy) to SUPER ALT+W
- Stop hyprpaper/swaybg before starting mpvpaper so the video wallpaper
  is actually visible
- Restart hyprpaper when toggling motion wallpaper off so the normal
  wallpaper is restored

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:26:31 +00:00
65d721c0fc Initial commit: Motion Wallpaper installer for Omarchy/Hyprland
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:23:21 +00:00