Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions plugins/animate-logo/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog

## 2026-08-15 — v0.1.0

### Full Frame Cycle for Frame-Style Animations

- Fixed frame truncation in `frame` style: when `duration_ms` is not set in the logo animation config, the plugin no longer caps the output to the 1200 ms default (e.g. 14 frames at 12 fps), which caused the animation to be cut short and restart from the beginning.
- When `duration_ms` is absent and `style` is `frame` with source frames available, the plugin now emits every source frame exactly once (e.g. all 36 frames of a kitty animation), letting the host loop the complete animation.
- Behavior for generated styles (`sweep`, `wave`, `rainbow`, `sparkle`, `breathing`, `none`) and for explicit `duration_ms` values is unchanged.
13 changes: 11 additions & 2 deletions plugins/animate-logo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,18 @@ fn main() {
let args = request.args;
let fps = clamp(args.fps.unwrap_or(12), 1, 60);
let frame_delay = 1000 / fps;
let duration_ms = std::cmp::max(frame_delay, args.duration_ms.unwrap_or(1200));
let frame_count = std::cmp::max(1, duration_ms / frame_delay);
let style = args.style.as_deref().unwrap_or("sweep");

let frame_count = if args.duration_ms.is_none()
&& style == "frame"
&& request.frames.as_ref().is_some_and(|sets| !sets.is_empty())
{
request.frames.as_ref().unwrap().len() as u64
} else {
let duration_ms = std::cmp::max(frame_delay, args.duration_ms.unwrap_or(1200));
std::cmp::max(1, duration_ms / frame_delay)
};

let frame_sets = request.frames.unwrap_or_default();

let frames: Vec<AnimationFrame> = match style {
Expand Down
Loading