Commit Graph
3254 Commits
Author SHA1 Message Date
Kristian Myram 335d1f56ac #2459: reject raw opens through docking command aliases 2026-10-27 20:30:13 +00:00
Kristian Myram 82123f0d02 #696: reject workspace saves while window positions migrate 2026-10-27 20:23:24 +00:00
Jeremy 44061a3b33 fix(installer): check the exact architecture-specific machine folder
The pre-signing check matched any folder named Program Files, so it rejected
a valid MSI when Windows resolves Program Files elsewhere, accepted the 64-bit
root for an x86 package and accepted a different app name. Build the expected
folder from the package architecture's resolved root and the policy name.
2026-10-27 19:13:29 +00:00
Anubhav RaiandClaude Opus 5 06a1e6d27b engine: entry names are compared the way a filesystem might (#2123)
Two names that differ only in case are one file on Windows and on macOS as they
come, and Win32 drops a trailing dot or space, so `clip.png` with `CLIP.png`,
and `a.png` with `a.png.`, still landed on each other: ten entries extracted to
nine files on APFS, one footage item holding the other's picture. Collisions are
now looked up by a key with the case folded and those characters off the end,
while the name written stays as the entry asked.

Found by CodeRabbit on the pull request.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-28 00:32:34 +05:30
tylerjenningsw cedc727da9 Merge remote-tracking branch 'origin/main' into fix/particle-birth-history
# Conflicts:
#	crates/effects/src/sim.rs
#	crates/render/src/lib.rs
2026-10-27 14:57:00 -04:00
Anubhav RaiandClaude Opus 5 a89fbdab8f engine: two template footage entries can't become one file (#2123)
The fallback name was never checked against the names already taken, so an
entry called exactly what the fallback produces took the same file: `media/1/a:b.png`,
`media/2/a_b.png` and `media/3/2-a_b.png` extracted to five files for six
entries, the third overwriting the second, and both items' footage pointing at
it. Deduplication now runs on the name actually written and counts up until it
is free.

The collision predates making the names safe (two entries named `a_b.png` and
`2-a_b.png` collide on their own), but sanitising gives more ways in, so it
belongs with it.

Found by CodeRabbit on the pull request.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-28 00:05:19 +05:30
tylerjenningsw ef825f2947 Merge remote-tracking branch 'origin/main' into enhance/pickwhip-index-refs 2026-10-27 14:13:51 -04:00
tylerjenningsw b5460f653b Roto Brush: a correction keeps the model prompted with what is left of a stroke (#1646)
Dropping the points a later stroke of the other kind painted over could leave
a stroke with none, even though most of it was still painted: a small Alt tap
in the middle of a large foreground dot removed its only point, and the
selected model was skipped for the classical cut. Points are now kept by the
resolved ownership under them, and a stroke that loses every sampled point
but still owns pixels is prompted from the one deepest inside them. A stroke
painted over completely still prompts nothing.
2026-10-27 14:13:40 -04:00
tylerjenningsw b2cace1320 Roto Brush: test that a stroke corrects earlier ones through the commands (#1646)
Green, Alt (red) over part of the object, then green there again, as the
Layer panel sends them through roto.stroke: the render follows the last
stroke, and Undo / Redo step between the two results.
2026-10-27 14:13:40 -04:00
tylerjenningsw 0f8a65f6c2 Disk cache: drop segmentations and frames made before strokes applied in order (#1646)
Segmentations and rendered frames are keyed by their strokes, which now
segment differently where strokes overlap; bumping both versions keeps old
entries from showing the old result. Frozen mattes are stored in the project
and are untouched.
2026-10-27 14:13:40 -04:00
tylerjenningsw 818ce2ab42 Roto Brush: model prompts follow the latest stroke (#1646)
A trained model is no longer prompted with both labels at one spot: points
along a stroke that a later stroke of the other kind painted over are
dropped, and the propagated matte's points, box and mask take this frame's
strokes over it.
2026-10-27 14:13:40 -04:00
tylerjenningsw af995ea26a Roto Brush: Refine Edge strokes apply in drawing order (#1646)
A Refine Edge stroke over an earlier Alt (erase) stroke now restores the band
there; the band carried from the previous frame stays under this frame's
strokes.
2026-10-27 14:13:40 -04:00
tylerjenningsw aae936e9bd Roto Brush: foreground and background strokes apply in drawing order (#1646)
A green stroke over an earlier Alt (red) stroke now restores the area: where
strokes overlap, the one painted last sets the hard constraint, for the cut,
the colour samples and the cleanup seeds alike.
2026-10-27 14:13:39 -04:00
tylerjenningsw ecc3e673bc Merge remote-tracking branch 'origin/main' into enhance/keyframe-text-clipboard 2026-10-27 14:13:38 -04:00
tylerjenningsw b1c0a2394d Merge remote-tracking branch 'origin/main' into enhance/batch-parent-matte 2026-10-27 14:13:37 -04:00
tylerjenningsw 2dcd1b27a9 Merge remote-tracking branch 'origin/main' into fix/947-preview-opening-audio
# Conflicts:
#	crates/ui-egui/src/lib.rs
2026-10-27 14:13:31 -04:00
Anubhav RaiandClaude Opus 5 471ef40e25 automation: the Scripting settings have two more spellings (#2131)
`Prefs::set` makes a JSON pointer of the key (`key.replace('.', "/")`), so
`scripting/allowScriptsWriteFiles` resolves as well as the dotted spelling, and
the page on its own (`{key: "scripting", value: {…}}`) replaces every setting on
it — `coerce` takes an object for an object, and the page deserializes with
`serde(default)`. A prefix check on `scripting.` let both through. The page is
now read from the key's first segment, split on either separator.

Found by CodeRabbit on the pull request; reproduced before fixing, with
`prefs.set {key: "scripting/allowScriptsWriteFiles", value: true}` answering
`{"scripting/allowScriptsWriteFiles": true}` under confinement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-27 23:37:32 +05:30
dotCooCoo 8ee9bc144b Keep failed scripts and selected panels out of recent script history 2026-10-27 11:06:19 -07:00
tylerjenningsw 8c7990c65f Merge remote-tracking branch 'origin/main' into fix/expression-value-color
# Conflicts:
#	crates/ui-egui/src/panels/effect_controls.rs
2026-10-27 14:05:11 -04:00
Anubhav RaiandClaude Opus 5 14b345c333 engine: a template's footage entry can't name a file outside the folder (#2123)
EffectCraft writes its own templates as `media/<item id>/<file>` entries, and
extraction trusted both halves. `base_name` splits on `/` and `\`, but the item
id was taken with `split('/')` alone, and it is pasted in front of a base name
another item already used. So a second `media/..\..\..\Startup\x/clip.mp4`
entry became `<dir>/..\..\..\Startup\x-clip.mp4`, which on Windows is three
folders up, with the attacker choosing how the name ends.

The id is now used only when it is one, and the name goes through
`safe_file_name`: separators, drive colons and NUL become `_`, and `.` / `..`
become `footage`. Reached from `templates.create` with `path`, from File ▸ New
from Template, and from a template dropped in the user Templates folder.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-27 23:34:41 +05:30
tylerjenningsw 238361e59f Menus: a pointer coming back into the window over another title switches menus (#1290) 2026-10-27 14:03:48 -04:00
tylerjenningsw 8220d96929 Menus: tests that hover switching leaves submenus, a disabled bar and the arrow keys alone (#1290) 2026-10-27 14:03:12 -04:00
Matej Kozlovský 3ad8ba9581 CLI: log warnings to stderr by default
The CLI installed no logger, so GPU warnings (a declined frame, out of
memory, fallback to the CPU) were dropped and an export silently rendered
on the CPU. Install the engine logger with a `warn` default (RUST_LOG
still overrides). Split out of #1415.
2026-10-27 18:52:16 +01:00
Anubhav RaiandClaude Opus 5 2d6e790fde automation: a confined agent can't start a script's code (#2131)
`script.run` and the Scripts menu are refused while file access is confined,
but a ScriptUI panel's script was not: `window.scriptPanel` runs it to build
the panel, `window.restoreScriptPanels` runs every remembered one,
`scriptui.click` / `set` / `mouse` / `close` dispatch events to its handlers,
and `script.runTasks` runs its `app.scheduleTask` tasks. A script reads and
writes files and reaches the network, so none of that may start while confined.

`prefs.set` is refused for the `scripting.*` settings for the same reason: the
engine already stops a script from granting itself the access the user withheld
(`Scripting::same_permissions`), and a confined agent writing it to the settings
file would hand it to every script run afterwards, long after the session.
`prefs.get` and the read-only `scriptui.list` / `scriptui.get` are untouched.

This is the "Running code" part of the F-11 audit; the other parts of #2131
are separate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-27 23:20:40 +05:30
tylerjenningsw 68e9d9e322 Animation presets: test that saved effect keyframes start at the playhead (#1971) 2026-10-27 13:44:37 -04:00
tylerjenningsw b74b89feb5 Animation presets: effect keyframes in presets saved by earlier versions start at the playhead too (#1971) 2026-10-27 13:44:36 -04:00
tylerjenningsw 337a6c2053 Animation presets: saved effect keyframes start at the playhead (#1971) 2026-10-27 13:44:36 -04:00
aiongg dd12ed8f9c Merge pull request #2518 from Silvertree2010/perf/export-speed
Export: encode while the next batch renders, skip transparent pixels when compositing
2026-10-27 13:42:31 -04:00
dotCooCoo 2c2c51ca0c Preserve recent script files across menu and settings module changes 2026-10-27 10:11:33 -07:00
vangel76andClaude Sonnet 5.5 36ec54f007 Merge upstream/main into warp-skip-discarded-plan
Upstream split lib.rs files into modules and moved engine commands/ to cmd/; this branch's change merges without textual conflicts.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 17:51:52 +01:00
vangel76andClaude Sonnet 5.5 6418c8c0a4 Merge upstream/main into camtrack-validate-input
Upstream split lib.rs files into modules and moved engine commands/ to cmd/; this branch's change merges without textual conflicts.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 17:51:50 +01:00
dotCooCoo 385b93b9c8 Merge updated font menu fallback branch 2026-10-27 09:50:31 -07:00
dotCooCoo dac5fb46f7 Preserve readable font names in the shared font menu 2026-10-27 09:48:22 -07:00
dotCooCoo 530c7eff36 Merge updated footage interpretation and preset branches 2026-10-27 09:40:57 -07:00
NetterSilverandClaude Opus 5.5 94399e62ff Pin movie export bytes
H.264 and ProRes exports of a 60-frame comp (several render batches, a
rotating stroked ring, a fading solid at a fractional position, a
Screen-mode shape, 8 bpc) must keep the exact bytes main wrote before the
two previous commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:40:41 +01:00
NetterSilverandClaude Opus 5.5 db41fa7980 Skip transparent pixels and quantise while compositing
Much of a layer buffer is often transparent (a stroked ring, a glow-padded
text layer, a precomp canvas), yet every destination pixel sampled it
bilinearly, and 8/16 bpc comps then re-quantised the layer's whole rotated
bounding box.

- Bilinear warps skip 16x16 source tiles whose pixels (and a one-pixel
  apron) all have zero alpha: their samples are transparent and were never
  drawn.
- The fast affine warp reports the rectangle it changed and, given the
  comp's levels, quantises each pixel as it blends it, so draw_comp has
  nothing left to re-quantise for that layer. quantize_px moves to
  effectcraft-raster for this.
- quantize_rect skips runs of four all-zero (+0.0) pixels, which quantise
  to themselves.
- to_rgba8 / to_rgba8_over convert row by row instead of per 4-byte item.

Every pixel stays bit-identical: tests compare the warp against the
reference path, fused quantising against quantising after blending, and
the zero-run skip against per-pixel quantising.

With the previous commit, demo comp to H.264 (`cargo xtask bench --scenario
demo --format h264 --frames 300`, 11 interleaved runs on a 16-thread Ryzen):
wall 9.26 s -> 6.97 s median (-24.8%), 8.55 s -> 6.55 s min (-23.3%); CPU
time -23%. Output byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:40:41 +01:00
NetterSilverandClaude Opus 5.5 d8bca3cdd9 Overlap movie encoding with rendering
Movie exports (H.264, HEVC, AV1, ProRes, uncompressed) rendered a batch of
frames on every core, then encoded it frame by frame while the render
threads waited. Each batch now encodes on a pool shared by all exports while the
next batch renders (Cx::frames_beside). With deferred GPU readbacks, or
where no thread can be started (wasm without threads), the two still take
turns. A panicking encoder becomes an export error.

H.264 frames are converted to 4:2:0 on the render threads, per frame, instead
of on the encoder's critical path. The conversion reads 8-bit levels from a
table and rounds without a libm call; both give the same values as before
(tested against the previous formula).

Demo comp (1920x1080, 300 frames) to H.264 on a 16-thread Ryzen, export
wall time -6% (median of 7 interleaved runs); output byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:40:41 +01:00
dotCooCoo e3480abf78 Upgrade saved effect parameters when applying animation presets 2026-10-27 09:40:00 -07:00
dotCooCoo 4b1c197055 Accept supported footage interpretation parameters 2026-10-27 09:35:34 -07:00
dotCooCoo 6da18d16df Merge composition proxy interpretation fixes 2026-10-27 09:23:22 -07:00
dotCooCoo 1c6cbd8c43 Include alpha interpretation in frame-blend cache keys 2026-10-27 09:22:27 -07:00
dotCooCoo 87eb51a089 Include alpha interpretation in frame-blend cache keys 2026-10-27 09:22:14 -07:00
vangel76andClaude Sonnet 5.5 9fc04e8fe3 Merge upstream/main into fix-1083-beat-marker-audio-pause
Conflicts came from upstream splitting crates/project/src/lib.rs and moving the
frames tests. Re-applied the branch's change in the new places:
- Layer::same_pixels_with now in crates/project/src/layer.rs
- Comp::same_pixels_with, same_settings(o, with_markers), pixel_form_with and the
  timing-marker helpers in crates/project/src/comp.rs (same_pixels_ignoring_markers
  stays removed)
- Project::reads_markers in crates/project/src/item.rs
- crates/ui-egui/src/frames.rs uses reads_markers/same_pixels_with; the branch's
  two marker tests replace the old ones in crates/ui-egui/src/frames/tests.rs

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 17:09:17 +01:00
vangel76andClaude Sonnet 5.5 2078b492d9 Merge upstream/main into rfx-text
text/layout: upstream split paragraph() into Para/place_line helpers and moved the tests to
layout/tests.rs. The branch's changes are re-applied there: the resolved paragraph direction
is passed to margins_for/avail_for/align_for (RTL point text with Justify sits flush right),
first_ascent/plausible_first and ParaLine.first/style_first (box first baseline is the d
height, vertical text keeps the ascent), and the Justify All last-line cost in
optimal_breaks. The branch's seven new layout tests moved to layout/tests.rs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 17:06:38 +01:00
vangel76andClaude Sonnet 5.5 d9620d9ca1 Merge origin/rfx-masks-shapes into local merge of upstream/main
Keeps the already-pushed branch history; the resolved tree is unchanged: render tests live in
crates/render/src/tests/ (mask_feather.rs registered in tests.rs).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 16:58:23 +01:00
vangel76andClaude Sonnet 5.5 ca00da2f55 Merge upstream/main into rfx-masks-shapes
render: upstream moved the tests_*.rs modules into crates/render/src/tests/; the branch's
tests_mask_feather.rs now lives at tests/mask_feather.rs and is registered in tests.rs.
path: rect() keeps the branch's explicit-outline version with an added NaN guard on the
roundness clamp bound (main's fix for the same panic).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 16:57:13 +01:00
vangel76 92e33beef0 Merge remote-tracking branch 'upstream/main' into gap-behaviors-presets 2026-10-27 16:51:00 +01:00
Jeremy ca36861bde fix(installer): resolve the wizard scope and folder correctly
Real msiexec runs (per-user and all-users, silent and wizard) found two defects
that the metadata fixtures cannot see:

- "Only for me" published ALLUSERS=2, so FindRelatedProducts treated the run as
  per-machine and skipped the existing per-user copy. An interactive upgrade
  left two registered products and uninstall left files behind. The page now
  leaves ALLUSERS unset for a per-user choice.
- Windows Installer resolves Program Files once, for the context it started in,
  so choosing "Everyone" in the wizard installed into the user profile with a
  machine-wide registration. The wizard now sets the new-install folder itself
  after the choice (Program Files, Program Files (x86) for 32-bit, or the
  per-user Programs folder). Silent installs are unchanged.

check-install-policy.ps1 now fails if either regresses.
2026-10-27 15:32:20 +00:00
dotCooCoo 93d8476c3f Derive the prior renderer key in the cache regression test 2026-10-27 08:32:06 -07:00
dotCooCoo c0f6151185 Preserve font name fallback in the shared dropdown menu 2026-10-27 08:31:12 -07:00