Commit Graph
2645 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 f36b2b3e6b Release 0.12.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 21:43:07 -04:00
Egon5000 09dad1a51f Timeline: a shape group's inner Contents draws no row, as After Effects elides it 2026-10-18 02:49:56 +02:00
MarekSpodBiedry 651ee5a78e Resolve effects/<match name> property paths in anim.applyPreset (#1746) 2026-10-18 01:10:30 +02:00
Brandon ThomasandClaude Opus 5.5 2a01226894 Release 0.11.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.11.1
2026-10-17 19:03:26 -04:00
Brandon ThomasandClaude Opus 5.5 45c9d22929 Release: install resvg for the macOS DMG background in CI
The 0.11.0 macOS release job failed after notarization with 'resvg not found': the shared
release workflow never installed it, and it was only present before via a warm cargo cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 19:03:26 -04:00
Brandon ThomasandClaude Opus 5.5 bba7abd224 Build: gate tests_services with a plain cfg(test) so clippy treats it as test code
clippy's allow-unwrap-in-tests only recognises #[cfg(test)], not cfg(all(test, ...)),
so cargo xtask ci failed on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 18:15:45 -04:00
Brandon ThomasandClaude Opus 5.5 8de1288a46 Release 0.11.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 17:06:17 -04:00
Madhav AgarwalandDeepSeek V4.1 Flash Free b113278a1c Fix #1275: open the commands' file dialogs without blocking the frame on Linux
rfd's Linux backend goes through the XDG desktop portal, and a blocking
`rfd::FileDialog` leaves the main thread waiting on the portal's answer
without pumping winit's events: while the Open dialog is up the window stops
answering the compositor, which offers to force-quit the app ("EffectCraft is
not responding"), until a file is picked.

The non-blocking host hook for the commands' dialogs (`rfd::AsyncFileDialog`
on a worker thread, run when the dialog closes) was macOS-only since #511.
Install it on Linux too. Windows keeps the blocking pickers (its dialog pumps
its own messages), and the panel buttons' pickers (Settings, effect file
pickers) are unchanged.

Checked headlessly against a mock XDG portal: with the hook the main thread
stays in the event loop while a worker blocks in the portal wait, `ui.inspect`
still answers 7.5 s after the dialog opened, and an answered dialog runs
File ▸ Import; without it the main thread itself blocks in the portal wait and
the app answers nothing until the dialog closes.

Co-Authored-By: DeepSeek V4.1 Flash Free <noreply@deepseek.com>
2026-10-18 00:48:08 +05:30
skylar taylor-barrick 2d805d1b69 Merge pull request #1748 from skylartaylor/import-and-open
Import templates and open originals within their own folders
2026-10-17 12:13:54 -06:00
skylar taylor-barrick 69bf44be0b Build: take craft-docpath from the merged craft-libs rev
craft-libs#169 is merged, so the fork pin is no longer needed. Pinned to
storytold/craft-libs 82a24b006eefa036b43c09a67fb9a3fbd17ffe63 (main after the merge) rather than the older 12281d07,
which predates resolve_absolute and the Windows colon refusal.
2026-10-17 12:03:59 -06:00
Moein Saharkhiz 8e59ccdb3a Fix #1231: keep autosave completion tied to its originating project (#1330) 2026-10-17 08:58:56 -06:00
MarekSpodBiedry b8d52cd8c4 Paste path operators below the shapes they act on (#1681)
Pasting Trim Paths, Wiggle Paths or a paint into a shape layer with nothing
selected put it on top of Contents, where it acts on no shapes. It now goes
to the bottom, as Add places it. Also fixes #1629.
2026-10-17 14:37:42 +02:00
MarekSpodBiedry 0e5b366574 Keep CC Simple Wire Removal between points A and B (#1724) 2026-10-17 14:33:06 +02:00
Egon 5000 5bcc9ed1e9 Merge remote-tracking branch 'origin/main' into menu-bar-native-behaviour
# Conflicts:
#	crates/ui-egui/src/menus.rs
2026-10-17 13:58:19 +02:00
arnav-hiwarkarandClaude Opus 5.5 c28daa479b #1714: test several comps, negative and malformed saved times
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 15:35:12 +05:30
arnav-hiwarkarandClaude Opus 5.5 ea67c46880 #1714: doc comments name the saved current times
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 14:40:44 +05:30
arnav-hiwarkarandClaude Opus 5.5 b9172fec2f #1714: reopen each comp at its saved current time
Layer times were already saved and read back as exact ticks; the values in
the issue are 34f, 315f and 3033f at 59.94 fps. The viewer was black because
the playhead wasn't saved: a reopened comp started at 0, before its layers.
The project file's view (`activeComp`, `openComps`) now also records each
comp's current time (`compTimes`), restored on open within the comp's frames.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 14:32:14 +05:30
MarekSpodBiedry 7146006c15 Duplicate the selected text animator or selector instead of the whole text layer (#1665) 2026-10-17 07:50:03 +02:00
MarekSpodBiedry 351f2591fd Fall back to the page's thread when new Worker throws in a sandboxed iframe (#1586) 2026-10-17 07:47:33 +02:00
MarekSpodBiedry 8f74c3790e Replace non-ASCII characters in EXR layer names so ProEXR export no longer panics (#1702) 2026-10-17 07:46:32 +02:00
heojunfoandClaude Opus 5.5 ee5c9ac2dd Advanced 3D: Accepts Shadows Only draws just the shadow (#1691)
The Advanced 3D renderer folded Accepts Shadows (Off/On/Only) into a
bool, so a shadow catcher set to Only drew as an ordinary lit surface.
The material now carries shadows_only. Such a fragment draws black at
the strongest shadow a light casts on it, as Classic 3D does, and it
goes in the blended pass so what is behind it shows through. The CPU
shader and advanced3d.wgsl get the same branch.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 13:31:08 +09:00
aiongg f82ce628ad Build: use craft-docpath from craft-libs 2026-10-17 02:20:50 +00:00
Matej Kozlovský 0fbe76b2bf Cryptomatte: CryptoAux enum instead of a positional bool; GPU test for every display mode (#473)
crypto_aux_image_with takes CryptoAux::{ColorsAndMatte, MatteOnly}, and
CryptoAux::for_display holds the rule for which displays read the ID
colours. A new GPU test checks every display x Matte Only against the CPU,
so the GPU fails the test if the shader starts reading RGB in a mode that
skips it (checked by mutation: forcing MatteOnly fails display 0).
2026-10-17 01:48:48 +02:00
NetterSilverandClaude Haiku 5.5 1ad17f608b Resolve Microsoft font names to installed metric-compatible fonts
Fixes #1677

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 23:50:29 +02:00
Ayberk A. 107cedb84c fix(effects): starred effects survive a restart (#1692)
Effects & Presets kept its favourites in `UiState::effects_favorites`,
which nothing writes out (only the workspace layout is saved), so the
stars were gone the next time the app opened. They now live in the
settings (`Prefs::effects_favorites`, saved when a star is clicked) like
the recent fonts and presets, survive Reset All like them, and a
hand-edited list loses empty and repeated ids on load.
2026-10-17 00:40:04 +03:00
arnav-hiwarkarandClaude Opus 5.5 6c3a08e780 Preview: an edit keeps frames only outside Solo changes and the shutter (#1641 review)
Turning Solo on or off hides or shows every other layer at every frame, so it
now recaches the whole comp. The kept span is widened by the comp's shutter
(phase and angle), since a frame's motion blur samples cameras, lights and
transforms up to three frames away. Comp::any_solo is shared with the
renderer so both read Solo the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 02:50:48 +05:30
Ayberk A. ab8af6ae95 test(script): per-key methods in another comp leave both key selections alone (#1531)
The worse half of #1531: when the property's comp remembers a key the user
selected, the old code didn't just do nothing, it eased, held or removed
that selected key instead of the one named. This test, written by
@switch87 in #1558, pins it: only the named keys change, removeKey(1)
removes key 1, the active comp stays active with its own key selection,
and the other comp's remembered selection comes back as it was. It fails
on the code before #1558 and passes on main.
2026-10-17 00:13:27 +03:00
arnav-hiwarkar 4fff7c624a Merge main into #1643 2026-10-17 02:38:53 +05:30
webdevtodayjason f368aa0df3 Viewer: keep unselected null outlines visible
Fixes #1642
2026-10-16 14:09:40 -05:00
Matej Kozlovský f8bd967861 gpu: honour wgpu env overrides in headless/CLI (with_env, WGPU_ADAPTER_NAME, WGPU_POWER_PREF)
GpuContext::request() now applies InstanceDescriptor::with_env() (WGPU_BACKEND,
WGPU_DX12_COMPILER, WGPU_VALIDATION, WGPU_DEBUG, ...), the same variables the
desktop app honours via egui-wgpu, and requests PowerPreference::from_env(),
defaulting to HighPerformance (an unknown WGPU_POWER_PREF logs a warning).

WGPU_ADAPTER_NAME (CLI/headless only; the desktop ignores it) picks the first
adapter whose name contains the trimmed value, case-insensitively. Empty or
blank counts as unset. Only the name is matched (backend via WGPU_BACKEND). A non-matching name is an
error that says so and lists each distinct adapter once as 'name (backend)', instead of wgpu::util::initialize_adapter_from_env's panic;
no adapters at all gets its own message.
2026-10-16 20:12:35 +02:00
caldiag 548001e1a9 fix: use timeline.revealProps from updated main instead of custom implementation, remove redundant test 2026-10-16 14:55:17 -03:00
caldiag 1e63c9d3e9 Merge branch 'main' of https://github.com/storytold/effectcraft into fix/fx-controls-property-double-click 2026-10-16 14:44:53 -03:00
aiongg 816ca95800 Footage: follow stored footage paths only on this computer or the project's share
Footage paths stored in a project are resolved through craft-docpath against
the project file when it is opened or imported: relative paths are taken from
the project's folder, and an item whose path is on another computer, names a
device or is a non-file URL is marked missing without being looked at. The
footage check, the changed-on-disk scan, Reload Footage, Relink, Edit Original
and Reveal in Finder resolve the path again before touching the file, and the
Project panel, Metadata panel and waveforms read no file details of missing
footage.

Lottie image assets are resolved against the Lottie file; one on another
computer is skipped with a warning. Files a 3D model names are read only when
local or on the model's own share.

Reveal in Finder refuses a folder that would open as an app or other bundle.

Files imported or relinked in this session are opened as given.
2026-10-16 17:43:58 +00:00
Matej Kozlovský d1c1e23bb9 xtask bench --repeat N: median/p90/min/max summary, compare by median
Runs every scenario N times (default 1, unchanged). Every run is still
appended to results.jsonl; with N > 1 one "kind": "summary" row per key
follows, whose metrics are the medians of the successful runs (user_s and
sys_s included, byte/instruction counts rounded) and whose summary holds
median, p90 (nearest rank, = max for N < 10), min and max. A failed run marks
the summary failed so the gate refuses it.

--compare uses the latest row per key; the table labels each side "median
of N" or "1 run" and warns when they differ, and --fail-over refuses such
keys. --repeat with --with is rejected. docs/testing.md documents the format.
2026-10-16 19:39:53 +02:00
Marco Arnulfo 9d56675da9 Text: drag a Range Selector's Start and End in the Composition viewer (#1011) 2026-10-16 18:45:11 +02:00
aiongg 1064911fc4 Edit: Edit Original opens only regular files with a footage media extension
A folder or bundle, a link to another kind of file, or a file whose extension
the footage importer doesn't take is refused with a message instead of being
handed to the system's default app.
2026-10-16 16:14:02 +00:00
aiongg 299223f112 Templates: Import Template writes embedded media only into its item folders
Each 'media/<item>/<file>' entry is written to '<template> Media/<item>/<file>'
only when <item> is all digits and <file> is a plain file name (not empty, '.'
or '..', no separators, and on Windows no drive, stream or device name), and
the written path is checked to sit in an item folder of '<template> Media'.
read_stored skips entries with absolute, drive or '..' names.
2026-10-16 16:14:02 +00:00
Vikram Bhaskaran 31d74e268d Normalize cardinal Wave Warp directions to preserve CPU and GPU parity. 2026-10-17 03:12:36 +11:00
Marco Arnulfo d32c57b093 Project: a new folder opens with its name ready to type (fixes #1658) 2026-10-16 16:26:32 +02:00
Marco Arnulfo ad4ed3981e Lumetri: hue/saturation curves stay inside their box beside a close point (fixes #1656) 2026-10-16 16:08:18 +02:00
detthandClaude Sonnet 5.5 2823abc40c fix(engine): report the keys keys.delete removed, not the keys selected
keys.delete returned the number of selected keys even when some of them
no longer existed, so a delete that removed nothing still reported success.
It now returns the number of keys actually removed, and a key that is gone
or listed twice is not counted.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JaA7tHy731qtvscjulrcfz
2026-10-16 13:55:29 +00:00
arnav-hiwarkar 1f81c813e1 #1641: keep RAM frames when adding or removing sources
Validate the previous content identity using the selected comp's layers
as well as its address. Otherwise a new solid changes the reachable
source set and prevents all frame carry. Read sources removed by undo
from the saved base snapshot, while still checking current values of
existing dependencies, project settings and nested comps.

Add regressions for short-solid add/delete, addition undo/redo, and
simultaneous edits to existing solid or nested-comp dependencies.
Both the addition and undo regressions failed before their fixes.

Validation on macOS:
- Frame-cache tests: 23 passed.
- cargo xtask ci: passed (3452 tests passed, 31 ignored), including
  workspace release Clippy, tests, docs, PDF deps, layers, assets and wasm.
  Local release builds used LTO=false and codegen-units=16; repository
  profile settings are unchanged.
- Release UI driver: cut, move, add and delete; all 15 cache audits pass.
  Adding/deleting a 2-3s solid retains 567/600 frames (only 59-91 recache).
  Undo/redo immediately restores all 600 frames.
- All 4,800 CPU cached-vs-fresh frame comparisons match at Quarter preview
  resolution; four full-comp playback sweeps have zero waiting steps.
2026-10-16 18:45:53 +05:30
Hamza 0c39995d0f Convert a shape layer's parametric path to a bezier path (#932)
`path.convertToBezier` only cleared `roto_bezier` on mask groups, so on a shape
layer it did nothing at all: a Rectangle, Ellipse or Polystar path stayed
parametric and its vertices could not be edited or animated. In After Effects
the command replaces such a path with an editable Path 1 of the same geometry.

The geometry is not re-derived. `parametric_path` calls the same
`effectcraft_path::{rect, ellipse, polystar}` functions `render::shapes::collect`
calls, with the same defaults for a property a group doesn't carry, so the path
that comes out is the shape that was on screen; `from_kurbo` and
`build::shape_path` then make an ordinary Path 1.

Masks are unchanged: shape items take precedence when selected, and with none
selected the command falls through to the old mask behaviour. Path Direction is
carried over rather than reset, since reversing a path is a separate command,
and the new path is left selected so its vertices can be edited straight away.

The parametric properties are read at the current time and the result is a
static path: a Size or Roundness animation cannot survive becoming a vertex
list, in After Effects either. Undo restores the parametric shape.
2026-10-16 18:13:08 +05:00
Marco Arnulfo 34f1ebfe55 Masks: the arrow keys nudge the selected points (part of #1288) 2026-10-16 14:42:03 +02:00
krinry f13429010f #1582, #1585: guard web serviceWorker against SecurityError in opaque contexts
In sandboxed iframes without allow-same-origin (or other opaque origin contexts), accessing `navigator.serviceWorker` throws a SecurityError synchronously.

- Guard `info().serviceWorker` evaluation with try/catch to return `false` on SecurityError (#1585)
- Guard PWA serviceWorker registration with try/catch to let the web app load rather than hanging (#1582)
- Add contributor credit entry for @krinry in `contributors/people.toml`
2026-10-16 18:09:38 +05:30
Gert Pellin 0bdf9ec5e3 Merge branch 'main' into expr-property-group-1619 2026-10-16 14:28:34 +02:00
BFlat 8f02f52a44 Merge pull request #1478 from midasmatterhorn/fix/cff-endchar-width-polarity
pdf: endchar takes its width by operand parity like the stems and rmoveto
2026-10-16 19:05:24 +07:00
BFlat d676de9ba4 Merge pull request #1565 from midasmatterhorn/fix/r4-smask-bpc-shift
pdf: a soft mask at an unsupported bit depth is ignored, not fatal
2026-10-16 19:05:12 +07:00
BFlat b9fddd3204 Merge pull request #1640 from krinry/fix/1611-layer-styles-context-menu
#1611: layer context menu has Layer Styles
2026-10-16 19:05:00 +07:00
bflatastic 9bdf05f34b Merge main into #1478; keep both sides of crates/pdf/src/cff.rs 2026-10-16 19:04:43 +07:00