Releases: jfreed-dev/niri-screensaver
Releases · jfreed-dev/niri-screensaver
v0.6.1
Added
- Bats unit tests + kcov coverage. A
test/suite asserts the bash scripts'
pure functions — effect-arg building,load_configdefaulting, logo
resolution/picking, toggle state, the kill-debounce (#4), battery gating, and
mirror-mode argument assembly. Both bin scripts now guardmain "$@"so they
can be sourced for testing. A new CI job runs the suite underkcovand
uploads line coverage to Codecov;make unitandmake coveragerun it
locally (both skip with a hint when the tool is missing, same as the linters).
Changed
- Security and dev docs refreshed.
SECURITY.mdnow lists 0.6.x as
supported (was 0.3.x) and documents the CI gates that guard the codebase.
TESTING.mdandLINTING.mdcover the new unit suite and the coverage job.
v0.6.0
Added
- Multi-monitor mode:
independent(default) ormirror. New
MULTI_MONITOR_MODEconfig key.independentkeeps the existing behavior —
each output runs its own driver and randomizes its own effect/logo.mirror
makes every output show the same effect: the launcher rolls one RNG seed
(and, whenRANDOM_LOGOis on, picks one shared logo) and passes them to every
driver via argv (--seed/--logo), sinceniri msg action spawnruns in the
compositor's environment and would not inherit exported vars. Each driver seeds
ttewithSEED + window, wherewindow = wall-clock-seconds / MIRROR_INTERVAL
(default 8s) — deriving the effect window from the shared wall clock, not a
per-process counter, is what keeps the monitors on the same effect at the
same time even though the surfaces spawn at different moments and animate for
different durations.tte's deterministic RNG then renders identical
animations on matched-resolution monitors; it degrades to "same effect,
different layout" when resolutions differ. Surfaced in the Noctalia plugin as a
Multi-monitor mode dropdown in the Effects section. Only applies with more
than one output; single-monitor setups are unaffected. - Bar widget: left-click is now a smart toggle. Clicking the Noctalia bar
widget previously always launched the screensaver; it now stops it if it's
already running and launches it otherwise, so it no longer has to be killed
from a menu or the CLI. Backed by a new quietniri-screensaver-launch is-runningcommand (exit 0 if running, 1 if not; also forwarded by
niri-screensaver-ctl) that the widget probes on click. Right-click still
opens the full Trigger / Stop / Toggle / Settings menu. - Bar widget: Quit and Reload menu items. The right-click menu gains
Quit (stop the screensaver and disable it, so idle won't relaunch it
until re-enabled) and Reload (stop the screensaver, restart the Noctalia
shell so the systray reappears, and leave the screensaver enabled — a one-shot
fresh start, run detached so it survivesqs kill).
Fixed
- Multi-monitor: surfaces no longer collapse onto one output under
focus-follows-mouse.niri-screensaver-launchpreviously spread one
Alacritty per output by cycling keyboard focus
(niri msg action focus-monitor-next) between spawns. With niri's
input { focus-follows-mouse }, window placement follows the pointer, not
keyboard focus, and the pointer isn't parked until after the spawn loop — so
every surface opened on the cursor's monitor and the others stayed blank. The
launcher now enumerates outputs once up front and pins each spawned surface to
its target output by window id
(niri msg action move-window-to-monitor --id <id> <output>), which is
independent of pointer/keyboard focus. Outputs are enumerated a single time so
N>2 monitors and mid-launch hotplug are handled deterministically. A new
NIRI_SCREENSAVER_SPAWN_PIN_TIMEOUT_SECSenv var (default2) bounds how long
the launcher waits for each surface to appear before moving on. Thanks to
@landryjeanluc for the report and root-cause analysis (#11). - Multi-monitor: dismissing one screen now wakes all of them. Each output
runs its own driver in its own terminal, and a keypress only reaches the
focused one — so on a multi-monitor setup, dismissing the active screen left
the others still running the screensaver. The driver now broadcasts a
terminate to its sibling instances on dismiss (dismiss_all→
terminate_sibling_drivers, which SIGTERMs the otherniri-screensaver run
processes via a/procscan that skips its own PID). Siblings exit through
the normal signal path and do not re-broadcast, so there is no signal storm.
Surfaced once #11's fix made surfaces actually spread across outputs.
v0.5.9
Fixed
- A white cursor block briefly flashed at the end of each effect, just before
the screensaver transitioned to the next one.ttere-shows the terminal
cursor when an effect finishes, undoing ourtput civis, and it lingered
until the next loop iteration re-hid it. The driver now passes
--no-restore-cursortotte(when supported andCURSOR_HIDEis on) so the
cursor stays hidden across the whole run.
v0.5.8
Added
- Sleep-on-battery threshold. New
BATTERY_MIN_PERCENTconfig key
(default0= disabled). When set,niri-screensaver-launchskips
auto-launch if the machine is running on battery below that percentage,
to save power. Plugged in (any AC/Mains adapter online) or no battery
present (desktop) never skips;launch forceoverrides the check.
Surfaced in the Noctalia plugin as a new Power settings section
("Skip on battery below %"), and reported inniri-screensaver-ctl statuswhen enabled. Battery state is read from
/sys/class/power_supply/*bytype(so adapter/battery naming is
irrelevant); multiple batteries use the most-drained one.
Fixed
niri-screensaver-ctl effectslisted every TTE effect twice.tte -h
prints the{beams,...}choices block twice (usage line + positional
args);get_effectsnow takes only the first occurrence (grep -m1).
v0.5.7
Documentation
- README "Creating your own" logo subsection now covers layout
(centering behavior, trailing-whitespace gotcha, blank-line padding,
icon+wordmark stacking) and includes a small size reference table.
Existing tool recipes (figlet,jp2a,chafa, patorjk web
generator) and theLOGO_FILE=... niri-screensaver-ctl testpreview
workflow are retained. noctalia-plugin/README.mdSettings table rebuilt with aWidget
column reflecting actual control types (toggle / spinbox / dropdown /
text + Browse / button), and the previously-missingLOGO_FILE,
SHOW_NOW_PLAYING, andNOW_PLAYING_DURATIONrows added. New
"Logos" section in the plugin README covers the dropdown's auto-
refresh behavior, the effective-dir resolution order, and a concise
layout/size primer that cross-links to the upstream README for the
full guide.
Added
- Noctalia plugin: dropdown selector for the logo file in the Logo
settings section. Lists*.txtfiles from the effective logo
directory (thelogoDiroverride if set, else the installed
share/logos/) and auto-refreshes when files are added or removed
— no Noctalia restart needed. Disabled when "Random logo per cycle"
is on, since the random picker overrides any specific selection.
Previously thelogoPathsetting had no UI and was only editable by
hand-editing the Noctalia settings JSON. - Noctalia plugin: fade-in / fade-out effect controls are now
NComboBoxdropdowns populated at startup from
niri-screensaver-ctl effects(deduped + sorted). First entry
(none)clears the fade. Eliminates the silent-no-op when a typo'd
effect name slipped past the free-text inputs. - Noctalia plugin: "Logo directory" now uses
NTextInputButton—
text input on the left, folder icon on the right that opens
Noctalia'sNFilePickerin folder-select mode. The picker starts at
your currentlogoDirif set, otherwise at the detected install
path. Picking a folder fills the text input; the input stays
editable for paste / type workflows. - Noctalia plugin: Logo section moved above Effects in the Settings
panel (matches typical edit frequency); within Logo, the file
dropdown is now first, then Random toggle, then directory..txt
extensions are stripped from dropdown display names; combobox
minimumWidthbumped to 320px to fit the longest shipped logo
names without truncation.
Changed
- Default seeded logo is now
niri-name-with-icon.txt(was
framework-name-with-icon.txt). Only affects fresh installs where
~/.config/niri-screensaver/logo.txtdoes not yet exist; existing
installs keep whatever logo was previously copied. To pick up the new
default, delete~/.config/niri-screensaver/logo.txtand re-run
niri-screensaver-ctl(or symlink any other logo from
share/logos/— all are still installed).
v0.5.6
Changed
- AUR PKGBUILD
optdependsdescriptions trimmed across both packages.
Dropped parenthetical / env-var noise:playerctlno longer carries
(SHOW_NOW_PLAYING=true),wlrctlno longer carries(recommended),
and theydotool/figletblurbs are slightly shorter. The env
var docs belong in the README, not in a pacman info pane. Cleaner
output frompacman -Qiandpacman -Si. Also reduces the volume
of false errors produced by CachyOS'sshellypackage manager,
which has a parser bug that splits optdep descriptions on
whitespace and treats each token as a separate package name
(standardpacman/paru/yaywere never affected).
v0.5.5
Fixed
- AUR
.installpost-install messages and the README "Wire it into
Noctalia" Option A now recommendcp -rinstead ofln -sfnfor
the plugin into~/.config/noctalia/plugins/niri-screensaver. With
a symlink, the plugin loads fine, but Noctalia's
PluginService.savePluginSettings()writes viash -c "mkdir -p '<dir>' && cat > '<settings.json>' << HEREDOC ...", and thatcat >fails
with permission denied because/usr/share/niri-screensaver/noctalia-plugin/
isroot:root 755. The write is fire-and-forget via
Quickshell.execDetached, so the user sees no error — they just
notice their plugin Settings changes silently revert on Noctalia
restart. Caught by an end-to-end install test on a fresh AUR install.
Tradeoff ofcp -ris that plugin updates frompacman -Syudon't
auto-flow into the user copy; the new note in both the post-install
message and the README tells users to re-runcp -rafter upgrades.
v0.5.4 — shellcheck SC2015 fix + AUR scaffold polish
Changed
install.shcache-refresh guards rewritten with explicit
if cmd; then action || true; firather than
cmd && action || trueto satisfy stricter shellcheck (SC2015).
Runtime behavior is identical — both forms no-op when the tool
isn't installed and don't break the install on cache-refresh
failure. Only the lint pattern changed. Caught by CI on a newer
shellcheck version than the one shipped locally.- AUR packaging scaffold (
packaging/aur/) received pre-publish
polish per a full pass againstAUR_submission_guidelines:
0BSDLICENSEper package dir (gates eligibility for official-
repo promotion), whitelist.gitignorein the publish recipe
(fail-closed against future file types accidentally landing in
the AUR repo), obfuscated maintainer email, and a corrected
first-time publish recipe usinggit -c init.defaultBranch=master clonesince AUR only accepts pushes tomaster. None of this
changes runtime behavior — strictly publishing hygiene.
v0.5.3 — fix .desktop Test action under launchers
Fixed
.desktop"Preview an effect inline" action wrapped in
alacritty -e ...so it works when invoked from a desktop
launcher (Fuzzel, Anyrun, GNOME Activities, etc.). The
underlyingniri-screensaver-ctl testneeds a TTY fortte
to render; without the wrapper, launcher invocations silently
no-op. CLI use was always fine. Alacritty is already a hard
runtime dep, so no new dependency.
v0.5.2 — desktop entry + hicolor icon
Added
- Desktop integration:
share/applications/niri-screensaver.desktop
andshare/icons/hicolor/scalable/apps/niri-screensaver.svg. The
.desktopentry exposes the primaryniri-screensaver-ctl launch
action plus twoActions=entries (Preview an effect inline,
Enable/disable screensaver) so launchers like Fuzzel/Anyrun/Walker
can right-click to the secondary actions. Icon is a charcoal-stroke
variant of the existing plugin SVG so it stays visible across
light and dark GTK/Qt themes (the plugin'sstroke="white"
version is intentional for Noctalia tinting and stays as-is). Both
install.sh and the AUR PKGBUILDs ship them to their respective
XDG paths and refreshgtk-update-icon-cache/
update-desktop-databasepost-install (silent no-op if those
tools aren't installed). - AUR PKGBUILDs scaffolded under
packaging/aur/— both
niri-screensaver(stable, tracks tags;pkgver=0.5.1with the
v0.5.1 tarball sha256 baked in) andniri-screensaver-git(HEAD,
with apkgver()that derives fromgit describe). Each ships a
$pkgname.installpost-install hook that points the user at the
niri window-rule snippet, the Noctalia plugin symlink command, and
the inlinenoctalia-customCommand.jsonfallback.
Pre-generated.SRCINFOfiles included so AUR sync is a clean copy.
packaging/aur/.gitignoreexcludes makepkg build artifacts (pkg/,
src/,*.pkg.tar.*, fetched tarballs, etc.) so a stray
git add -Afrom the repo root doesn't accidentally commit them.
packaging/aur/README.mddocuments first-time publish and per-release
update flow, including the structurally identical.gitignorethat
belongs in each AUR-side repo. All declared deps (alacritty,
niri,jq,python-terminaltexteffects) plus optdeps
(noctalia-shell,playerctl,wlrctl,ydotool,figlet)
verified present in Arch repos or AUR. End-to-end test build
confirmed:makepkg --verifysourcepasses,makepkg -dproduces a
92Kniri-screensaver-0.5.1-1-any.pkg.tar.zstwith the expected
41-file layout, and the-gitPKGBUILD'spkgver()resolves
correctly to<tag>.r<count>.g<short-hash>. - CI:
.github/workflows/release.ymlauto-creates a GitHub Release
on anyv*tag push. Pulls the matching## [X.Y.Z]section out of
CHANGELOG.mdviaawkand feeds it togh release create --notes-file. Falls back to the bare tag name if no matching section
exists. Backfilled releases for v0.4.0/v0.5.0/v0.5.1 so the
"Releases" sidebar reflects the actual ship history. Future cuts
only requiregit tag vX.Y.Z && git push origin vX.Y.Z.