Introduced by the commit before this one. Dropping the `WRITES` entry changed
that refusal's wording from `cannot write` to `cannot read`, so the assertion
moved to the part both share — `outside the automation roots` — but
`/elsewhere/proxy.mov` is not absolute on Windows, where it is refused for that
instead and the assertion fails. The gate runs ubuntu only, so it stayed green.
A sibling of the write root under the temp directory is absolute on every
platform, so the refusal is the one the test is about.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A shape's painted bounds can be tiny enough (a 1e-305 px rectangle) that
the fit scale overflows to infinity. Non-finite bounds are skipped and a
non-finite scale returns an error before anything is written, instead of
storing infinity in the document.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Asked for on the PR: #1347 allows `file.createProxy` a name that is not a path,
because the engine reads it as an Output Module template, and the `WRITES` entry
added here refused exactly that. Dropped, so the classification is #1347's alone.
Nothing is opened by it. A proxy named outside the roots is still refused —
`cannot read` now rather than `cannot write`, which is #1347's to settle — so the
test asserts the refusal and no longer its wording. A relative name is now
accepted and resolves beside the saved project, inside the write root, which the
test pins so this does not quietly come back.
The lookup this PR is for is untouched: `file.createProxy` stays in
`QUEUES_AN_OUTPUT`, so a proxy queued from a project with no file is still
refused rather than landing in the home folder.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
layer.transform's fit / fitWidth / fitHeight ops took the layer's size
from render::source_size, which returns (0, 0) for layers without a
source item — shapes and text — so the ops matched nothing and silently
did nothing, for the shortcut, the menu item and the command alike.
When the source size is empty and a fit op runs, the size falls back to
the layer's painted content bounds at the current time, and the anchor
goes to the bounds' centre: content bounds live in layer space, where a
shape is centred on the origin and text sits above its baseline, so
(w/2, h/2) would fill the frame but land off-centre. Reset and the
other ops keep the source size, so their defaults are unchanged.
The regression test asserts what the viewer shows — the painted bounds
mapped to comp space span [0, 0, 640, 360] after fit, and fitWidth
spans the width centred vertically — for a rect shape and a text layer.
Co-Authored-By: GLM-5.3-Flash <noreply@z.ai>
Edit > Clear follows panel focus: with the Project panel focused it
redirects to project.delete, which removes the selection at once when
nothing uses it. With a text edit open, that deletes the composition
being typed into — the user is working in it — and undo restores the
item but not the active composition. During a text edit the redirect
stands down (Clear does nothing) and the Edit menu's Clear entry is
disabled, mirroring how Deselect All stands down in #2096.
Co-Authored-By: GLM-5.3-Flash <noreply@z.ai>
Edit > Duplicate replaces the layer selection with the copies, but an
open in-canvas text edit stayed on the original layer: typing kept
editing a layer that was no longer selected. When the duplicate leaves
the edited layer deselected, end the edit the way #2096's Deselect All
does (text_edit::end_edit), in the command every caller — menu, shortcut,
MCP — dispatches through.
Co-Authored-By: GLM-5.3-Flash <noreply@z.ai>
Every undoable edit keeps the previous project for undo, so the comp it touches
is shared and Arc::make_mut deep-copies it: every layer and every keyframe. An
edit therefore costs time in proportion to the comp's size, and a script that
sets many keyframes in a big comp goes quadratic (a 1,600-layer build with
~100k sampled keys took ~45 minutes).
Comp::layers is now a Layers collection backed by Vec<Arc<Layer>>: copying the
stack copies pointers, and only the layer an edit changes is copied. The API
mirrors Vec<Layer>; serialized form is unchanged (a list of layers).
Comp::layer_mut and the iter_mut().filter/find call sites use find_mut /
iter_mut_where so they copy only the layers they actually change.
- prop.addKey in a 400-layer comp: 1.36 ms -> 0.16 ms per key (flat in comp size)
- the 1,600-layer script build: ~45 min -> 47 s, frames pixel-identical
- regression tests: an edit leaves the other layers shared with undo; layers
round-trip as a plain list
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkpGcKfWyCudfSsQNiWAaG
Resolve the Interpret Footage form against main's split into
interpret_footage_form and project_settings_form, keeping the Cineon
Settings fields and the pointUnits readback. Restore the Arc, rayon
prelude and cineon_frame imports that main's explicit use lists dropped.
Resolve viewport-edge insertion through the full Timeline outline, skipping
moving layers even below the viewport. Cancel a gesture if any captured
layer disappears before its ID can be interpreted as a layer index.
Cover intermediate drops, selected groups, deletion of the owner or another
group member, Undo/Redo, and later independent drags.
The dev profile keeps line tables only, which keeps builds fast and test binaries small; panics and backtraces still name file and line. Debugger sessions still need local variables and column breakpoints, so add 'dev-full': the same settings plus full debug info. The fast profile remains the default.
* Honor CARGO_BUILD_TARGET in FreeBSD packaging for aarch64 release builds
The shared release workflow cross-compiles FreeBSD aarch64 in the x86_64 VM and sets
CARGO_BUILD_TARGET. package.sh ignored it: it built for the host, read binaries from
target/release, and took the arch from uname -m (amd64 on that VM), so the aarch64 build
would have produced an x86_64 archive with x86_64 binaries.
When CARGO_BUILD_TARGET is set, pass --target, read binaries from target/<triple>/release,
name the archive from the target arch, and skip the --version smoke test (the binary cannot
run on the x86_64 host). Unset keeps the previous behavior.
* Reject unsupported CARGO_BUILD_TARGET and gate the smoke test on the host triple
Only x86_64-unknown-freebsd and aarch64-unknown-freebsd are accepted when CARGO_BUILD_TARGET
is set; anything else exits 2 instead of being labelled freebsd-x86_64.
The --version smoke test now runs when CARGO_BUILD_TARGET is unset or equals this host's
full FreeBSD triple, so a native explicit target is still checked.
Finish reordering from the stored egui drag owner and primary-button
release even when wheel scrolling culls the originating row. Cancel
disabled, interrupted or stale gestures before they can arrange layers.
Cover scrolling in both directions, selected groups, Undo/Redo, later
drags and cancellation boundaries, including opening Settings mid-drag.
Make the existing no-op control cross the drag threshold.
Fixes#2492.