mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-10 20:32:31 +00:00
* Place decodes, fits and renders in a background job File > Place Embedded / Linked started with Session::start, and Session::start_place_bytes for bytes with no path, now run the decode, flatten, resize and SVG render on a worker (prepare_place) and insert the layer when the job is applied (apply_place). Inline callers (execute, the CLI, headless MCP, actions) behave and return exactly as before. Part of #10031. * Dropped and placed files no longer freeze the window on desktop With background jobs on, File > Place and files dropped on the canvas start the place as a job (JobsUi.place). Free Transform begins when the layer has landed, a failed or cancelled place is reported and the drop queue goes on, and a drop that arrives meanwhile waits for it. The place shows its progress in the status bar instead of the modal dialog, so the view stays usable. Part of #10031. * Tests: compare place job results without the layer id Layer ids come from a counter shared by every session, so a job and an inline place in two sessions never get the same one. * Dropped files stay with the document they were dropped on Each queued canvas drop now carries its document's id. A file is placed only while that document is active: files dropped on a document in another tab wait until it is back in view, and are discarded with a message when it is closed. Web drops, read by the shell after the drop, go to the document the drop landed on. Before, the next queued file went into whichever document was active when the previous place finished, failed or was cancelled, in the background and inline paths alike. * Remove the unused file_open import * fix: address background placement review feedback * fix: preserve drop targets and interrupt placement pixel stages * fix: qualify placement inbox document identity * test: wait for background placement in app drop regression * fix: retain queued drops while external document jobs run * test: clone rendered pixels from drop-managed buffers * test: cover band rows channels and queued-drop resumption * Place decodes and fits in the background: dropping a large file no longer freezes the window Placing a file decoded, flattened and resized on the UI thread; a large PNG froze the window for seconds (#10031). `place_bytes` is split into a session read, `prepare_place` (decode, flatten, fit, translate, SVG render at placement scale) and `apply_place`, and runs through `jobs::run`, so File › Place and canvas drops run on a worker with progress and cancel. The window follows the job: status-bar progress, Free Transform when the layer lands, and drops queued per target document. Review fixes on the way: - a path and byte drop queue entry records its target DocId, so files dropped on one document never land in another after a tab switch, and closed documents discard theirs; - the closed-document notice stays up for a frame instead of being cleared by the next queued placement; - the queue is bounded (32 files / 256 MiB) so drops waiting on another tab cannot grow it without limit; - flatten and resize stop at the job's interrupt, and a place skips the modal progress dialog only when the status bar actually shows its progress; - the placement's `doc` is kept only for SVG input, through the importer's `is_svg_input`; - the interrupted-composite test uses an opaque fixture that varies by row and channel, and checks the composite against the layer's stored pixels. * Place reads its file in the job, and refuses a huge canvas as before file.placeEmbedded and file.placeLinked read the whole file in the command before the job started, so a path dropped on the canvas or picked in File > Place still blocked the window for the read. The place now carries the path and reads it in prepare_place: on the job's worker in the background, on the calling thread inline (wasm, background jobs off), with the same read_file limit and error text. Whether the source is a vector one is decided once it has been read. The job's flatten check returned Other("the document canvas is too large to flatten"), where the place used to give flattened_checked's BadParams for file.place naming the canvas size. Both now share check_flattenable, so the old error type and message are back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Path drops aren't capped, and a discarded drop wakes the queue The 32-file cap on the drop queue counted path drops, which hold no file contents while they wait, so dropping 40 files on the canvas placed 32 and refused 8 where main placed them all. The count cap now applies to browser drops only (each holds its whole file); the byte budget still bounds those. When place_next_dropped discarded a closed document's files it returned without asking for another frame, so another document's queued files waited for the next input event. It now requests a repaint when files remain, keeping the one frame that shows the notice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>