Commit Graph
875 Commits
Author SHA1 Message Date
Dylan M. Taylor f0bc6d6fcf engine: hold each clip once in Frame Hold Options and stop Project Manager folder walks following links 2026-11-03 23:48:26 +00:00
JohnandClaude Opus 5.5 26bcdbb9d7 fix(ui): Remove Attributes says that ticked attributes are removed (#3789) (#4003)
* fix(ui): Remove Attributes says that ticked attributes are removed (#3789)

The report's effect stayed because it was unticked in the dialog to turn
it off; a ticked box means "remove". The dialog now says so above the
attributes. The test covers the hint, an unticked effect being kept, and
an effect offered ticked and removed with the defaults.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ui): Paste / Remove Attributes offer only the effects they act on (#3789)

The dialogs listed Essential Sound's effects (Dialogue's noise reduction,
EQ…), which the commands keep, so a ticked box promised a removal that
did not happen. The engine's rule is now public as
clip_ops::is_attribute_effect and the dialogs use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 00:09:51 -05:00
Jonathan CardosoandBrandon Thomas afdb8019c1 media: say which colour values no tag gave (#4086) (#4089)
With no colour tags, FilmCraft decodes with BT.709 transfer and
primaries and the matrix by frame size, and probe and media.colorInfo
showed those values with nothing saying they were defaults, so an
untagged file looked the same as one tagged BT.709.

VideoStreamInfo gets color_assumed (optional, left out when unknown):
which of the matrix, transfer and primaries no tag in the file gave.
MP4/MOV and Matroska take it from the same sources as the colour, APV
from its colour description, and AVI, MXF and Y4M mark all three.
probe prints it as video.color_assumed and media.colorInfo as assumed,
next to the unchanged metadata.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-03 00:04:13 -05:00
Jonathan Cardoso 92939f71bf #3948: Time interpolation applies when a clip's frame rate differs from the sequence's (#3949)
* #3948: time interpolation applies when a clip's frame rate differs from the sequence's

A 24 fps clip in a 29.97 sequence at 100 % rendered the same with Optical
Flow or Frame Blending as with Frame Sampling, repeating one frame in five:
interpolation_blend gave up whenever the speed was 100 %. It now gives up
at 100 % only when the media's frame rate matches the sequence's, so it
takes the sequence rate too. Clips at the sequence's own rate still never
fetch a second frame.

* #3948: a still image gets no in-between frame

A still reports 29.97 fps and returns the same picture at every time, so
in a sequence at another rate it now passed the frame rate check: Optical
Flow ran on two copies of one frame, and the GPU plan fell back to the CPU
for nothing. media_interpolation skips still sources, and the item layer,
media_image and the GPU plan all ask it.

* #3948: an in-between frame never comes from past the clip's source out

A reversed clip starts 1 tick before its source out, so on a source frame
boundary interpolation_blend paired its last frame with the frame at the
source out, at a weight near 1: the first frame showed media the trim had
cut. A forward clip could end the same way (23.976 on 29.97, 5 frames
ending on a source frame blended in 20 % of the next one). Speed changes
had this already; rate conforms at 100 % now take the same path. When the
later frame starts at or past the source out, the clip shows its last
frame alone. The later frame always starts after the source in, so the
other end needs nothing.
2026-11-03 00:03:41 -05:00
Jonathan Cardoso f4f3dd5eff engine: timeline.move reads a time object and names an entry it cannot use (#4113) (#4116)
A moves[] entry gave its time only as integer ticks. Any other form, or
a missing clip or track, dropped the entry: alone it failed with "need
`moves`", next to other entries only those moved and the call said ok.
`time` now goes through tick_or_time_p like timeline.place's sourceIn,
and an entry without a usable clip, track or time is refused by its
index before anything moves.
2026-11-03 00:03:35 -05:00
Jonathan Cardoso 96d8e22c2d Image-sequence export reports the stills it wrote, not the path it was given (#4018)
* fix(export): an image-sequence export reports the stills it wrote

An export to `a.png` as an image sequence writes `a000.png`, `a001.png` and so on, but the
job's result, `file.exportMedia`'s `path` and the CLI's "exported" line all named `a.png`,
which does not exist.

The report now names the first still, the name `file.import` and `probe --image-sequence`
take for a sequence. `file.exportMedia` and `export.quick` name it as `path` up front, from
the frame count `export.resolve` uses, and add `lastPath`. The CLI prints both. A single
file keeps its path.

Fixes #4009

* fix(automation): a cancelled image-sequence export is cleaned up by its stills' name

Since `file.exportMedia` names an image sequence's first still as `path`, the MCP cancel
clean-up took `a000` as the stem: it left `a001.png` and every later still, and the `a.srt`
sidecar, behind. The result now also carries `basePath`, the name the stills are numbered
from, and the clean-up goes by it.

* fix(automation): an image-sequence cancel clean-up keeps the base name and finds .jpeg stills

An image-sequence export numbers every still, a single frame included, so a file under its base
name (`a.png`) is never its own: cancelling one deleted a user's `a.png` if it was saved during
the export. The stills of a `.jpeg` sequence were left behind instead, since the extension was
read as a format name, and `jpeg` names Motion-JPEG there; `file.exportMedia` keeps `.jpeg`
for a JPEG sequence.

* fix(automation): a cancelled image sequence removes only the stills it numbered

The clean-up matched any `<stem><3+ digits>.<ext>` written during the export, so cancelling an
export to `a.jpeg` could delete `a1000.jpeg`, the first still of an export to `a1.jpeg` in the
same folder. It now takes the digits and the last index from the result's `lastPath` and removes
only those names: `a000.jpeg` to `a120.jpeg` for a 121-frame export.
2026-11-03 00:03:30 -05:00
Jonathan Cardoso 258e4c45fe engine: the Metadata panel's Out Point is the last frame kept (#4114) (#4117)
metadata_fields subtracted a frame from mark_out, so the Out Point read
one frame before the Out mark. Everywhere else mark_out is the start of
the last frame kept: source_range adds a frame to get the end, and the
Project panel's Video Out Point shows it as is.
2026-11-03 00:03:26 -05:00
Jonathan Cardoso 1a864d1eae Import by a relative path: '..' climbs out of the document folder, and media paths are resolved once (#3998, #4001) (#4004)
* interchange: '..' climbs out of a relative document folder (#3998)

join popped a '..' only while the base had more than one part, which kept
an absolute path at its root but also kept a relative folder's first part:
`edit` + `../media/a.mov` gave `edit/media/a.mov`. A relative base now loses
any folder to '..' and keeps a leading '..' past its start; an absolute base
still stops at its root.

* engine: a document given by a relative path has its media resolved once (#4001)

interchange::import passed the document's folder as given, so a document
opened by a relative path gave media paths relative to the working directory,
and MediaPool::follow then took them from the document's folder a second time
(edit/edit/sub/a.mov). The folder now comes from the document's absolute path,
as doc_path::resolve already takes it.

* interchange: a '..' after a base that ends in '..' is kept (#3998)

std::path::absolute keeps '..' on POSIX, so a document opened as
`edit/sub/../cut.xml` (or `../cut.xml`) gives a base that ends in '..'.
join treated that as the root of an absolute path and dropped the media
path's own '..', looking for `edit/sub/../media/b.mov`. Now only a real
root (`/`, `C:`) absorbs a '..'.

* interchange: a document folder's own '..' is resolved before its media paths (#3998)

Keeping a '..' after a base that ends in '..' let a media path climb above
the root: importing ../cut.xml from /work gave /work/../../media/b.mov,
which craft-docpath refuses. join now resolves the base's own '.' and '..'
first with the same rule as the media path's (take off the last folder,
keep it past the start of a relative path, drop it at an absolute root), so
both /work/edit/.. and /work/.. with ../media/b.mov give /media/b.mov.

* interchange: join reads a folder's root as craft-docpath does, and drops empty names (#3998)

join counted one root part, so `..` could take the share off
`\\srv\share\..\edit`, and it kept empty names, so `./` + `clip.mov` gave
`/clip.mov` and a repeated separator gave `..` an empty name to remove.
The folder's root is now read as craft-docpath reads it (none, `/`, `C:\`,
drive-relative `C:`, `\\host\share`, `//host/share`, `\\?\C:`,
`\\?\UNC\host\share`). Below it, empty names and `.` are dropped and `..`
takes off the last name, is dropped at an absolute root and kept past the
start of a relative folder. One table-driven test covers the path forms.
2026-11-03 00:03:06 -05:00
842d3ca567 lumetri.presetThumbnails: write through the host and keep the grid to the presets (#4030)
* lumetri.presetThumbnails: write through the host and keep the grid to the presets

The PNG was written with std::fs::write instead of the session's Services,
the path every other export takes (#379), so on hosts without a filesystem
it trapped and elsewhere it ignored the host's file handling. The grid was
also as wide as `columns` asked (up to 32) whatever the number of presets:
there are ten, and 32 columns of 1920 px cells made a 61 572 x 1 084 image,
over a gigabyte of f32 pixels and a 267 MB PNG for one query. Columns now
stop at the number of presets shown. Found by fuzzing commands with hostile
parameters (it took over 10 s per call in a debug build).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* render: the preset grid copies thumbnails with checked slices

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-03 00:02:50 -05:00
Jonathan CardosoandBrandon Thomas 8ce79afd23 captions: SCC and MCC export name the characters they drop or replace (#4023) (#4036)
CEA-608 has no code for some characters (the ellipsis, CJK) and the SCC
and MCC writers dropped them, or sent a close basic-set one (’ as '),
without saying so. The CEA-708 service in MCC sent ? the same way, for
instance for an em dash.

charset_warnings lists each such character once, with how often and
the first caption that has it, using the writers' own tables, and
captions.export returns the list as warnings. The list is capped at
20 characters per stream plus one summary line.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-03 00:02:10 -05:00
wweimao f3f1afd160 M10.7: fix per-character Stroke and Stroke 2 controls (#3938) 2026-11-03 00:01:43 -05:00
Jonathan Cardoso a4bc8edd50 captions: TTML export writes the track language, import keeps it (#4025) (#4038)
TTML and DFXP exports always wrote xml:lang="en", whatever the caption
track's language. The document now carries the language: export takes
the track's, TTML import reads xml:lang (a language tag of at most 35
characters, else a warning), and captions.import takes an optional
language that wins over both.
2026-11-03 00:01:18 -05:00
0535926e87 engine: AAF/OMF export takes bitDepth as "24" too, and refuses anything but 16 or 24 (#4019) (#4020)
* engine: AAF/OMF export takes bitDepth as "24" too, and refuses anything but 16 or 24 (#4019)

plan_from read bitDepth with u64_p, which takes only numbers, so "24" (the
form describe lists, "16|24") fell back to 16 without a word, and `as u16`
let 65560 wrap to 24. It now takes 16 or 24 as a number or a numeric string
and refuses any other value.

* engine: the bitDepth refusal test covers OMF export too

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 00:01:01 -05:00
Jonathan Cardoso baddebdc30 interchange: EDL media relinked with Align Timecode lands on the file's own time (#3990) (#3996)
* interchange: EDL media relinked with Align Timecode lands on the file's own time (#3990)

An EDL's source times are timecodes, but its media items had no start
timecode, so Align Timecode had nothing to align from and a clip relinked
after an offline import kept its timecode as media time (the file's last
frame). EDL media now starts at timecode 0, and the relink shift reads each
timecode at its own file's rate, as the import-time rebase does.

* engine: EDL relink test checks the placeholder is listed missing, not its offline flag (#3990)

#4000 stops flagging EDL clips named only by clip name offline, so the setup asks media.findMissing instead, which lists the item either way.

* engine: the EDL relink test also runs with 25 fps media (#3990)

make_movie_at takes the frame rate. Under a 24 fps EDL a 25 fps file's timecode must be read at 25 fps: with the old shift (old_rate.tick_of(b - a)) the clip lands at -149 s instead of 1 s.
2026-11-03 00:00:45 -05:00
Jonathan Cardoso 351a713835 interchange: EDL clips named only by clip name are missing, not made offline (#3997) (#4000)
An EDL line with no `* SOURCE FILE:` guesses its file from the clip name in
the EDL's folder. When that file wasn't there the importer flagged the clip
offline, which Link Media reads as "made offline": the folder search, Relink
Others and the prompt on open all skip it. It is now a missing file, as an
unfound `* SOURCE FILE:` is.
2026-11-03 00:00:40 -05:00
Brandon ThomasandClaude Opus 5.5 8c171a0ab8 engine: mask discard test checks the cancel flag, not the worker's timing (#3899)
replacing_the_project_drops_pending_tracking_jobs asserted the discarded job
reported cancelled or finished within ~100 ms. jobs.list has no cancelled
field, so on slow CI runners the worker had not finished yet and the test
failed (b3aeb7c3, 53b937ab). Check the cancel flag that discard sets
synchronously instead.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 16:10:08 -05:00
b3aeb7c3df Apply background mask tracking in headless sessions (#3303)
* Apply background mask tracking in headless sessions

Fixes #3302

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: drop pending mask-tracking jobs when the project is replaced

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix: drop mask-tracking jobs started on a replaced project via document epoch

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-01 15:31:44 -05:00
.CooCoo af28e9acee History: each step shows the icon of the tool or command that made it (#3776)
* History: each step shows the icon of the tool or command that made it

Each undo and redo step now keeps the id of the command that made it,
through undo, redo, merged and grouped steps and the history limit.
The History panel paints that command's icon before each label: a
timeline tool's icon for the commands the tool runs, FilmCraft's own
icon for other commands that have one, and a plain square for the rest
and for edits made outside a command. Undone steps draw their icon dimmed
like their labels. The Open row has no icon. history.list is unchanged.

* History: ripple trims show the Ripple tool's icon

A ripple trim's undo step records its own id, timeline.trim.ripple,
whether it comes from a Ripple tool drag, a ripple edit point in trim
mode or a dynamic ripple trim, and the History panel shows the Ripple
tool's icon for it. Trim mode nudges, Extend Edit to Playhead and dynamic
trims record the edit point's kind (timeline.trim, timeline.roll or the
ripple id) instead of the outer trim command, so a regular trim shows the
Selection tool's icon and a roll shows the Rolling tool's icon. Trim
Previous and Next Edit to Playhead show the Selection tool's icon.

* History: icon targets on a part-scrolled row match the drawn icon

The History panel registered each row's icon target from the row rect after clipping it to the scroll area, so on a row partly scrolled out the target moved off the drawn icon, and an icon scrolled out entirely was still registered. The target is now the drawn icon's rect clipped to the scroll area, registered only while part of it shows.

* History: Apply Default Transitions to Selection shows the plain square

The trim. family gave trim.applyDefaultTransition the Rolling tool's icon, although the command adds transitions at the selected edit points and makes no rolling edit. It now shows the plain square, as the sequence transition commands do.
2026-11-01 15:15:33 -05:00
JohnandClaude Opus 5.5 90f388b6ba fix(ui): the Project panel's Zoom sizes List thumbnails and the Freeform canvas (#3774) (#3871)
* fix(ui): the Project panel's Zoom sizes List thumbnails and the Freeform canvas (#3774)

The footer's Zoom slider only sized Icon view's cards. In List view it now sets
the thumbnail size (the row height follows it) when Thumbnails are shown, and
is disabled when they are not, as there is nothing for it to size. In Freeform
view it scales the canvas: cards keep their stored positions and sizes, are
drawn scaled, and a drag moves a card by its distance on the unscaled canvas.
The default size draws both views as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ui): a zoomed List thumbnail keeps room for the item's name (#3774)

With large thumbnails the thumbnail covered the name and ran into the next
column. The Name column is now drawn wide enough for the thumbnail and
120 points of name; its saved width is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ui): zoomed Freeform commands use the width the cards are drawn at (#3774)

The card menu (Stack, Unstack, Clip Size), Align to Grid and Save Arrangement
sent no width, so the engine laid unplaced cards out at its 800-point default
and could save positions from different rows than the zoomed canvas shows.
They now send the same unscaled width the view lays the cards out at, and the
engine's parameter lists name the width they already read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ui): Freeform card and canvas menus act on their own bin (#3774)

A card's menu now stacks, unstacks and resizes only the selected cards of
its own bin, which its canvas width lays out; a selection that also holds
items of another bin left them laid out at this canvas's width. Save
Arrangement saves the bin of the canvas it was opened on, which can be a
floating bin window, instead of the bin the main panel shows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 15:15:00 -05:00
NetterSilverandClaude Haiku 5.5 2a8ae10919 Refuse non-finite curve coordinates in effects.setParam (#3792)
Found while testing crates/engine/src/commands.rs:4246 (json_to_param, Curve branch)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-01 15:14:35 -05:00
5ed4952d43 Add shared custom colors and complete marker editing (#1435)
* M3: Add shared custom colors and complete marker editing

* #1435: refine native colors and range endpoint flags

Use the macOS Colors panel for custom label colors and reuse the established egui picker on other hosts. Preserve draft confirmation, exact sRGB values, native text shortcuts and project ownership. Compact the swatches and center the add control, split range glyphs across their endpoints, localize the new controls, protect newer marker edits from stale dialogs, and cover the behavior with rendered UI and hit-test regressions.

Co-authored-by: Codex <noreply@openai.com>

* #1435: preserve imported palettes and marker double-click ownership

Union saved OTIO palettes across timelines with deduplication, bounded capacity,
first-name preservation and explicit overflow warnings. Keep null authors
consistent with omitted fields, and consume marker double-clicks before the
work-area gesture so opening the editor does not alter project history.

Correct the CSV URL column and schema documentation. Add six regressions for
palette retention/capacity, author handling, and physical overlapping gestures.

Validation: full cargo xtask ci (3666 passed, 45 skipped), 42 rendered UI tests,
and strict workspace/all-target Clippy on Rust 1.99.1.

Co-authored-by: Codex <noreply@openai.com>

* #1435: retain OTIO swatch names and generator labels

Ignore orphan name entries when retaining saved palette names so input ordering
does not hide valid names after the first 64 entries. Keep names bounded by the
retained palette and preserve existing valid names.

Include generator preset labels alongside custom label colors in OTIO metadata.
Add regressions for orphan-prefixed name maps and three generator kinds with
preset/custom colors through actual export/import round trips.

Validation: both regressions failed before fixes; all 72 interchange tests and
full cargo xtask ci pass (3668 tests, 45 skipped), plus strict workspace/all-target
Clippy on Rust 1.99.1.

Co-authored-by: Codex <noreply@openai.com>

* #1435: preserve distinct OTIO generator item identity

Use exported FilmCraft item IDs for generator media identity so identical
content can retain distinct source names, labels and custom colors. Repeated
references to one source item still share a single imported media entry.

Preserve content-based fallback for missing or invalid item IDs. Cover black
video, bars and tone, and color mattes with distinct items/shared references,
plus legacy and malformed identity metadata.

Validation: distinct-generator regression failed before fix; legacy compatibility
passed. All 74 interchange tests and final full cargo xtask ci pass (3670 tests,
45 skipped); strict workspace/all-target Clippy also passes on Rust 1.99.1.

Co-authored-by: Codex <noreply@openai.com>

* #1435: align Edit Marker layout and add safe marker navigation

Give the editor a wide aligned form, larger Notes area, side action column,
and grouped palette with vertical marker types. Expand the Web Link field
with the form and keep actions accessible in small windows.

Previous/Next saves valid edits as one Undo step and stays with the original
sequence/source owner, including coincident markers. Invalid drafts stay open;
unchanged navigation and Done add no history. Keep native/shared color pickers,
Author, Notes, URL validation and immediate marker creation.

Validation: all 45 rendered sequence/marker UI tests pass, including five new
navigation/owner/validation/layout regressions. Native macOS layout, picker
Cancel and exact single-step Undo restoration verified. Full standard cargo
xtask ci passes 3675 tests (45 skipped), doctests and all remaining gates;
strict Rust 1.99.1 workspace/all-target Clippy also passes.

Co-authored-by: Codex <noreply@openai.com>

* #1435: refine Edit Marker proportions and action alignment

Narrow the dialog to 680 logical pixels and keep the core order Name,
Time/Duration, Notes, Color and marker type. Place Author after the type-specific
options as secondary metadata. Preserve our palette, custom picker and range controls.

Use consistently sized, centered rounded action buttons with a primary Done action.
Shorten Delete Marker to Delete and remove the navigation helper and unused translations.
Keep the existing navigation save/validation/Undo semantics and automation IDs.

Validation: all 45 rendered marker/sequence UI tests pass, including small-window
action accessibility. Actual macOS layout and no-op Previous/Next/Cancel verified.
Full standard cargo xtask ci passes 3675 tests (45 skipped), doctests, formatting,
Clippy, translations, layers, assets and 49 WASM crates. Strict Rust 1.99.1
workspace/all-target Clippy passes separately.

Co-authored-by: Codex <noreply@openai.com>

* #1435: tighten marker layout and validate text editing

Use a narrower aligned form with Author below Name, bounded scrolling Notes,
left-aligned colors, centered actions and an inline Web Link URL/open icon.
Remove the legacy Flash Cue choice while preserving imported marker types.

Constrain timecode typing/paste to complete numeric colon-separated fields,
validate drop-frame labels and frame bounds, and disable Done for invalid timing.
Preserve high-frame-rate timecodes and point-marker semantics when Duration is
unchecked. Route native/menu clipboard and text Undo commands to focused fields;
explicit engine commands retain project Undo and selection semantics.

Validation: standard cargo xtask ci passes 3679 tests (45 standard skips),
doctests, fmt, strict workspace/all-target Clippy, i18n, layers, 69 assets and
49 WASM crates. Also passed 48 rendered marker/sequence tests and strict Rust
1.99.1 Clippy. Actual macOS clipboard, bounded Notes, point save and exact Undo
were checked. Windows/Linux desktop interaction remains pending.

Co-authored-by: Codex <noreply@openai.com>

* M0: Wait for frame-worker recovery before asserting

Do not treat a nonempty request queue as proof of worker death in the
panic-recovery regression. Keep waiting for all injected faults and enough
post-fault completions, then drain the queue without adding more seeks.
Retain the exact fault-count, successful-recovery and empty-queue assertions
and bound the wait with a two-minute deadline.

The inherited test failed twice in independent fork CI. It did not reproduce
locally: baseline passed 20 normal and 10 delayed-report runs; the repair
passed 50 normal and 10 delayed-report runs. No product or marker UI changes.

Validation: standard cargo xtask ci passed all 4485 tests (52 standard skips),
doctests, formatting, strict workspace/all-target Clippy, i18n, layers,
69 assets and 49 WASM crates.

Assisted-by: OpenAI Codex

---------

Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <codex@openai.com>
2026-11-01 03:04:14 +01:00
aiongg dfb5fe7021 Integration: wasm32 builds: media_queue is native-only, the sequence source-audio arm gets a boxed fill and a mutable mixer 2026-10-31 05:08:42 +00:00
aiongg e0298254b5 Integration: tests and dialogs meet the merged PRs (clip mismatch off in drop tests, save panel keeps caption names, Rename name optional, audio pane scroll, sequence source audio guard, workspace list, project hover label); drop the duplicate edit-marker test file 2026-10-31 04:24:16 +00:00
aiongg f65e2bc5cd Integration: #1864 #2922 #2434 adapt tests: reserved proxy outputs exist early; duplicate move entries fail as BadParams 2026-10-31 04:09:49 +00:00
aiongg 89ee11ae30 Integration: satisfy clippy (craft_ui::ComboBox in the FX choice, move_group and play_direction helpers, as_chunks in the relink test) 2026-10-31 03:39:23 +00:00
aiongg 8a01ebd46a Integration: #2847 #2282 adapt the interchange tests to the 7-argument clip helper and boxed MediaClip 2026-10-31 03:39:23 +00:00
aiongg 9f7a9d6342 Merge integration track timeline 2026-10-31 03:39:23 +00:00
aiongg 199cb8df1c Merge integration track ui3 2026-10-31 03:39:22 +00:00
aiongg 5f845f41a2 Merge integration track ui1 2026-10-31 03:39:22 +00:00
aiongg 01608757f5 Merge integration track fx 2026-10-31 03:39:22 +00:00
aiongg d6b1265dc4 Merge integration track text 2026-10-31 03:38:55 +00:00
aiongg 8595147b71 Merge integration track i18n 2026-10-31 02:17:34 +00:00
aiongg bf0386bf76 Merge integration track sys 2026-10-31 02:17:26 +00:00
aiongg 69ed33ae57 Merge integration track io 2026-10-31 02:17:17 +00:00
aiongg bf1a400b27 Merge integration track export 2026-10-31 02:17:03 +00:00
aiongg c2ac002f8f Merge PR #3684: Render Effects In to Out renders only red segments, like the reference app (#1220) 2026-10-31 02:16:02 +00:00
aiongg 9626e4403a Merge PR #3473: Keep a clip's transitions when copying and pasting it
# Conflicts:
#	crates/engine/src/commands.rs
2026-10-31 02:15:50 +00:00
aiongg 624248a00a Integration: #3251 re-apply the selection_follows_playhead pref in settings/{prefs,schema}.rs 2026-10-31 02:15:39 +00:00
aiongg 856089eccc Merge PR #3251: Settings: Selection Follows Playhead persists across restarts
# Conflicts:
#	crates/engine/src/settings.rs
2026-10-31 02:15:39 +00:00
aiongg 5d1a49d3f6 Merge PR #2921: edit: ripple sync-locked captions with deleted items (#2873) 2026-10-31 02:15:20 +00:00
aiongg 810320933d Merge PR #2612: Clip Mismatch Warning: a first clip that doesn't match an empty sequence asks
# Conflicts:
#	crates/engine/src/commands.rs
#	crates/engine/src/settings.rs
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/zh-cn.tsv
#	crates/ui-egui/src/lib.rs
#	crates/ui-egui/src/panels/timeline.rs
2026-10-31 02:15:20 +00:00
aiongg 8f16aea983 Merge PR #3714: bs: Add Bosnian (bs) to the interface languages 2026-10-31 02:14:54 +00:00
aiongg c3a2478518 Merge PR #1555: fix(control): sequence.settings without params reports the settings instead of opening a dialog 2026-10-31 02:14:10 +00:00
aiongg 6f4f383ca4 Merge PR #2705: #2489: an imported shortcut set is always listed; .kys files explain why they can't be read 2026-10-31 02:14:06 +00:00
aiongg b2f5d2eca1 Merge PR #2136: #2024: dialog commands the engine defaults can be bound to a key 2026-10-31 02:13:56 +00:00
aiongg 59695f22ae Merge PR #2344: i18n: Turkish (tr) interface catalog (#1377) 2026-10-31 02:13:56 +00:00
aiongg e5e3c2b881 Merge PR #2984: Recovery: retain durable journals and contain autosave worker failures 2026-10-31 02:13:48 +00:00
aiongg 435432394a Merge PR #2738: Link Media: Offline All is saved, so reopening the project doesn't ask again 2026-10-31 02:13:48 +00:00
aiongg 0a55c5e4e1 Integration: #2470 use Session::document_epoch instead of a second project counter; port marker menu and ruler double-click to timeline/{menus,interact}.rs; move test to tests/it 2026-10-31 02:13:47 +00:00
aiongg 104005be04 Merge PR #3052: Fix FCPXML slideshow imports and missing-media relinking (#2837)
# Conflicts:
#	crates/interchange/README.md
2026-10-31 02:13:42 +00:00