Skip to content

Releases

2.2.1 — a damaged settings file can no longer kill the timer

Choose a tag to compare

@valerkaaa valerkaaa released this 04 Nov 12:26

2.2.1 — a damaged settings file can no longer kill the timer

A hardening release: the daemon survives whatever is written into its state directory, and a real suspend test writes a real log.

Shutdown Timer

Fixed

  • A damaged settings.json no longer kills the daemon. Numeric settings
    land straight in $(( )), and a bare name there is fatal under set -u: a
    hand-written "notifyEarlyMins": "abc" ended the process on the next reload
    (abc: unbound variable), and the widget restarted it straight into the same
    crash — with a pending shutdown lost. Every numeric setting is now validated
    and clamped to the range the manifest and Service.qml already document
    (early warning, overlay seconds, snooze step, snooze limit, battery
    threshold): a string falls back to the default, an absurd number is clamped
    instead of obeyed. tests/test_state_files.sh damages all three state files
    (settings, state, schedules) and proves the daemon survives the damage, keeps
    its documented ranges, and still arms, snoozes and cancels afterwards.
  • suspend/hibernate no longer fail silently: if neither systemctl nor the
    Omarchy helper works (no resume device, no logind seat), the log says so
    instead of the timer just going back to IDLE.

Install or update

omarchy plugin add https://github.com/valerkaaa/omarchy-shutdown-timer --enable
# or
omarchy plugin update honor.shutdown-timer

Full notes in CHANGELOG.md.

2.2.0 — the daemon cannot be killed by a malformed command

Choose a tag to compare

@valerkaaa valerkaaa released this 04 Nov 12:26

2.2.0 — the daemon cannot be killed by a malformed command

A hardening pass after the review, plus a bar mark optically matched to its neighbours and screenshots generated rather than hand-made.

Shutdown Timer

Hardening pass after the review: the daemon can no longer be killed by a
malformed command, and the bar mark is optically matched to its neighbours.

Added

  • The README screenshots are generated, not hand-made. tools/screenshots.sh
    captures every surface (five bar states, popup, overlay, vertical bar) live on
    both themes and builds states.gif from them. tools/card_bbox.py finds a
    card by its own frame, and tools/frame_check.py proves the finished crop
    really frames it — a capture in the wrong coordinate space still looks fine
    and was shipping the desktop behind the popup. One capture is cut, never two,
    so the measured box and the pixels cannot drift apart mid-shot.
    tools/acceptance.sh runs the same check on the committed images.

Fixed

  • A malformed control line no longer kills the daemon. The control channel
    is a plain file any process in the session can write, and the daemon used to
    evaluate it unchecked: set:abc:poweroff reached $((abc * 60)) and, under
    set -u, ended the process — taking the user's scheduled shutdown with it.
    The daemon now validates every command (minutes 1..1440, action whitelist,
    HH:MM range, snooze count, schedule id charset and weekday 1..7) and logs
    the rejection instead of dying. Covered by tests/test_input.sh.
  • A schedule id with a regex metacharacter (.*) was used as a grep
    pattern on removal and deleted every schedule; ids are now plain
    [0-9A-Za-z]+.
  • The state badge cut itself out in black, which read as dirt around the
    mark on a light bar. The badge is now outlined in the surface it is painted
    on (bar or popup background), so it reads as a clean notch on both themes.
  • Deprecated QML signal-handler parameters (onChanged:/onModified: using
    the injected value/code) replaced with formal parameters; the Dropdown
    used a non-existent onValueChanged and is now on its real changed.

Changed

  • Bar mark sized by painted ink, not by box. The Nerd Font glyphs beside
    the widget paint 11–12 px inside the 16 px icon canvas; the mark now uses the
    same canvas and paints ~12 px, so it no longer overpowers the row. The stroke
    and the state badge scale with the slot, and the widget takes exactly one
    27 px icon slot when idle (the label gutter only exists while the countdown
    is on screen).
  • Shape.CurveRenderer for the mark: the ring is anti-aliased instead of
    stair-stepped at bar size.

Install or update

omarchy plugin add https://github.com/valerkaaa/omarchy-shutdown-timer --enable
# or
omarchy plugin update honor.shutdown-timer

Full notes in CHANGELOG.md.

2.1.0 — icon pass

Choose a tag to compare

@valerkaaa valerkaaa released this 28 Oct 13:47

2.1.0 — icon pass

2.0.0 — always cancellable

Choose a tag to compare

@valerkaaa valerkaaa released this 28 Oct 12:51

2.0.0 — always cancellable, schedule, i18n, dry run