A terminal already gets a live `[1/1] frame 16/180 ... ~14.2s left` line while
`effectcraft-cli render` runs. A program that starts the CLI (FilmCraft runs it to
render a composition for a clip) reads stderr through a pipe, so it saw nothing
until the render ended.
`--progress` prints one line per update instead, at most four a second:
progress <frames done> <frames total> <seconds elapsed> <seconds left, or - when unknown>
It has no effect on a terminal, which keeps its live line. Without the flag
nothing changes.
Documented in the usage text, the module header and docs/agents.md.
Tests: cargo fmt --check and cargo clippy --all-targets -D warnings pass; the
effectcraft-cli tests pass except render_out_is_relative_to_the_working_directory,
which already fails on Windows (it compares a canonicalize()d `\?\` path with the
path the CLI prints) and is unrelated to this change.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Evaluate the third cube coordinate symmetrically to retain the intended centerline tie. Keep the existing pixel oracle and tolerance.
Scope the Mem fixture mutex unwrap allowance so the original strict CI can validate this base.
Co-authored-by: Codex <codex@openai.com>
CPU renders kept one frame per thread in flight with no cap, so heavy comps
could be OOM-killed. EFFECTCRAFT_CPU_INFLIGHT=N renders at most N frames at
once through the existing capped path; unset keeps today's behaviour. With a
GPU cap too, the smaller cap holds for the whole batch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
Quit EffectCraft and Finder's Quit send `ViewportCommand::Close`, and
the close button sends the window's close request. In each case eframe
drops the window while AppKit's run loop is still running. On a Mac
with a Touch Bar, AppKit's Touch Bar code then raises an uncaught
Objective-C exception (`-[_NSTouchBarFinderObservation invalidate]`)
and the app crashes (storytold/craft-libs#3).
After the unsaved-changes check, `close_or_quit` calls
`craft_quit::on_close_request` from craft-libs, pinned to the rev that
craft-docpath already uses. When nothing holds the window open, it
cancels the close and quits through `-[NSApplication terminate:]`,
which still runs `on_exit` (window position, workspace, crash-recovery
cleanup). The prompt for a modified project still holds the window.
The window close after a lost graphics device takes the same route.
On other platforms it does nothing. pdfcraft adds craft-quit the same
way (storytold/pdfcraft#1533).
A quit while the window is minimized or hidden still closes the window
as before: eframe does not run `ui` then, and the unsaved-changes check
and the new call both run from `ui`.
`terminate:` ends the process before `eframe::run_native` returns, so
the log line for the closing window moves from `main` into `on_exit`.
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>
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>
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.
The picture comes from an item's proxy while Use Proxy is on, but the
Project panel, the Viewer, project.summary and footage.info asked only
about the item's own file: a proxy that couldn't be decoded (an AVI with
an unsupported codec, say) left the layer empty with no reason given.
They now ask FootageSource::item_problem, which gives the proxy's reason,
said to be the proxy's, for footage and compositions alike.
One list of movie extensions, in effectcraft-project, with AVI added:
FilmCraft reads AVI 1.0 / OpenDML. Tests against ffmpeg fixtures: Motion
JPEG with PCM audio, an unsupported codec (imports and says why it has no
picture), a file that isn't an AVI (an import error), and a damaged one
(a truncated recording imports as far as it goes; a garbled packet loses
its own frame only).
FilmCraft reorders AAC channel configuration 12 (7.1) to WAVE/SMPTE order,
as it does 3 to 6, so 7.1 AAC's left channel was mixed as the centre. The
downmix oracle test gains 6.1 (a program config element, left in AAC's
order) and 7.1 AAC fixtures.
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.
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>
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>