Fix copy/paste transition causes bad audio #1880

Open
bmatherly opened 3:44pm on July 29, 2026 wants to merge 160 Ξ” into mltframework/shotcut master from
transition_paste

Pull Request Overview

  • Opened on July 30, 2026
  • Status Open
  • Commit count 2 with first commit July 30, 2026

Total Delta

160 Total Diff Delta

Open Days

Open 37 weekdays

Test Delta

0 Diff Delta in Test Files
Breakdown by Phase

How long has this pull request spent in each phase of its lifecycle?

Fraction of total time Business days Phase
 
0.0 days Authoring 1 commit before pull request opened for review
 
0.0 days Awaiting first review
 
36.9 days Revising work with 1 commit in response to 1 review that left 4 comments

Total time for pull request still awaiting merge (longer than repo's target): 36.9 business days

Author avatar

Fix copy/paste transition causes bad audio

Comments Threads Pending Resolution

ljharb reviewed on July 30, 2026
ljharb left a comment

## Pull request overview

This PR updates multi-clip paste operations in `TimelineDock` to better preserve transitions when copying/pasting a track/tractor, addressing a reported issue where pasted transitions could cause incorrect audio.

**Changes:**
- Detect transition β€œmix” clips in pasted MLT playlists and skip inserting them as normal clips.
- Recreate skipped transitions via `AddTransitionByTrimOutCommand` after inserting adjacent clips.
- Adjust inserted clip in/out points and insertion positions to account for skipped transition entries.

Comments suppressed due to low confidence (3)

**src/docks/timelinedock.cpp:4538**
* A transition is added whenever pendingTransitionDuration > 0, even if the transition tractor's right-side clip could not be resolved (pendingTransitionRightIn < 0 / pendingTransitionRightClip invalid) or does not match the current clip. In those cases this can add a transition between the wrong pair of clips. Gate the transition creation on successfully matching the current clip to the transition's right clip, but still reset the pending-transition state either way.
```
if (pendingTransitionDuration > 0) {
const int rightClipIndex = clipIndexAtPosition(trackIndex,
overwritePosition);
const int leftClipIndex = rightClipIndex - 1;
if (leftClipIndex >= 0 && rightClipIndex >= 0
```
**src/docks/timelinedock.cpp:4532**
* This code now overwrites clips at overwritePosition (= position + info.start - skippedTransitionDuration), but the group-restore pass later in this function still looks up overwritten clips using position + clipInfo.start. When transitions are skipped (skippedTransitionDuration > 0), those lookups can resolve to the wrong clip (or blank), causing copied group membership to be restored incorrectly for pastes that include transitions.
```
const int overwritePosition = position + info.start
- skippedTransitionDuration;
MAIN.undoStack()->push(new Timeline::OverwriteCommand(m_model,
trackIndex,
overwritePosition,
MLT.XML(&clip),
false));
```
**src/docks/timelinedock.cpp:4303**
* A transition is added whenever pendingTransitionDuration > 0, even if the transition tractor's right-side clip could not be resolved (pendingTransitionRightIn < 0 / pendingTransitionRightClip invalid) or does not match the current clip. In those cases this can add a transition between the wrong pair of clips. Gate the transition creation on successfully matching the current clip to the transition's right clip, but still reset the pending-transition state either way.
```
if (pendingTransitionDuration > 0) {
const int rightClipIndex = clipIndexAtPosition(trackIndex,
insertPosition);
const int leftClipIndex = rightClipIndex - 1;
if (leftClipIndex >= 0 && rightClipIndex >= 0
```

Resolved Comment Threads

No resolved comments have been left on this PR.