Skip to content

fix(project): leave text holds past the end of the clips out of the timeline - #3362

Merged
richiemcilroy merged 3 commits into
mainfrom
fix/timeline-unreachable-holds
Oct 26, 2026
Merged

richiemcilroy merged 3 commits into
mainfrom
fix/timeline-unreachable-holds

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Fullscreen text cards pause the recording clock, and TimelineConfiguration::duration() adds their length to the timeline. Clip trims and deletes do not move text, so a card can end up after the last clip. Its length was still counted, but no frame maps there:

  • the editor's timeline and transport ran past the content;
  • exports stopped at the first unmapped frame, short of the promised duration (96 frames instead of 126 in the repro);
  • the card was never rendered either way.

hold_windows() now drops holds that start after the clips have ended. They hold no frame and are never reached, so they no longer count towards duration(). A hold starting exactly at the end is still a closing title. Everything else derives from hold_windows(): frame mapping, editor ripple maths, caption projection and audio. So the timeline length, playback, audio and export now agree. The Tauri editor's holdWindows() gets the same cutoff for its total duration (timeline-holds.ts, context.ts); its other uses convert times inside the clips, where a hold past the end changes nothing.

Exported pixels do not change: these exports already ended at the last clip. Only the length the timeline reports changes, for projects with a card past the end.

Tests

  • New unit test holds_left_past_the_end_of_the_clips_are_not_counted in cap-project: fails on main, passes here.
  • editing/mapping/duration-covered and editing/export/hold-past-end pass, so their strict xfails are removed. They were the known main bugs for this: 1876 of 20000 FULL sequences failed coverage on main.
  • The verify edit model (crates/verify/tests/edits) gets the same documented rule, written independently. editing/mapping/holds and editing/mapping/all compare engine and model on 20000 random edit sequences each at FULL.
  • The core reference model already leaves projects with text unchecked. The editing check now gates on exactly that, rather than on "no holds".
  • zoom_inputs_invalidate_when_framing_or_timing_changes added its hold at 50 s, past the end of its 20 s clips. That hold now rightly changes nothing, so the test now adds it at 12 s, inside the clips, and still checks that a hold invalidates the cached zoom samples.
  • timeline-holds.test.ts (Vitest) checks the TypeScript cutoff against the same cases.
  • Local, macOS: editing FULL 80/80 pass, captions FULL 19/19; lib tests for cap-project (196), cap-rendering (411), cap-editor (219) and cap-export (47) pass.

Not tested by hand: the editor UI with a card past the end. CI's GPUI unit tests cover the timeline model.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; the previous frontend duration mismatch is fixed, and no new actionable issues were found.

Summary

Stops fullscreen text cards beyond the clips from adding unreachable time.

  • Text holds past the clips no longer lengthen the timeline.

Reviews (3) · Last reviewed commit: "fix(desktop): leave text holds past the ..." · Reviewed by Greptile

@vercel

vercel Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
cap-status Skipped Skipped Oct 26, 2026 12:57pm UTC

@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

@richiemcilroy
richiemcilroy marked this pull request as ready for review October 26, 2026 12:34

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

View 1 other finding in Capy.

Open in Capy

Comment on lines +1997 to +2005
let clips_end = self.clips_duration();
let mut held = 0.0;
windows.retain(|(start, end)| {
if start - held > clips_end + CLOSING_HOLD_TOLERANCE {
return false;
}
held += end - start;
true
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Editor shows extra time

Rust now drops past-end holds, but the Tauri editor's holdWindows() still counts them. With a 3.2-second clip and a one-second card at 5.4 seconds, totalDuration() still returns 4.2 seconds while Rust returns 3.2 seconds. The player displays the longer duration and lets users seek beyond the playable content.

Update the frontend hold calculation and its callers to use the same cutoff.

Knowledge Base Used: Export and editor rendering

Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/project/src/configuration.rs
Line: 1997-2005

Comment:
**Editor shows extra time**

Rust now drops past-end holds, but the Tauri editor's `holdWindows()` still counts them. With a 3.2-second clip and a one-second card at 5.4 seconds, `totalDuration()` still returns 4.2 seconds while Rust returns 3.2 seconds. The player displays the longer duration and lets users seek beyond the playable content.

Update the frontend hold calculation and its callers to use the same cutoff.

**Knowledge Base Used:** [Export and editor rendering](https://app.greptile.com/cap/-/custom-context/knowledge-base/capsoftware/cap/-/docs/export-and-editor-rendering.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

@richiemcilroy
richiemcilroy merged commit d92c21a into main Oct 26, 2026
60 checks passed

This branch was successfully deployed

1 active and 1 inactive deployments
Preview – cap-web — ccbbccfb Deployed Oct 26, 2026 by vercel[bot]
Preview – cap-status — ccbbccfb Deployed Oct 26, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant