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`.
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.
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.
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.
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.
normalize() canonicalizes whatever part of a path exists, which on Windows adds
the verbatim prefix to some paths and not others, so a file under a folder
that isn't on disk failed the project-folder check against an existing
project folder. The check failed closed (access refused); it now drops the
prefix from canonical drive paths so both sides compare.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>