Commit Graph
187 Commits
Author SHA1 Message Date
yoriswind 2e210c0aae Scope Actions tool recording guard to the active take 2026-11-06 13:40:05 -08:00
yoriswind 5f480238d0 Reconcile five Classic Actions commands with current main 2026-11-06 09:29:48 -08:00
FredApps aee46a2fc6 Merge remote-tracking branch 'origin/main' into fix/10164-final-prune-u2 2026-11-06 17:28:48 +01:00
David Mann ec5eb1e2d0 Merge commit 'refs/fixprs/main' into HEAD 2026-11-06 10:21:59 +01:00
Khawar Zamman Wani 123b2032c4 Web build: Place runs a slice per frame, so a large PNG no longer freezes the page (#10164, rebased onto main)
The remaining commits of the stack, applied on top of the squash-merged #10147:

- PNG decodes in resumable steps of rows (PngDecodeRows, shared with decode_rows)
- PNG imports as a document in resumable steps (io PngImport, text metadata and
  document build in bounded steps)
- Jobs can run a slice at a time where there are no threads (StepWork,
  cooperative sessions, Session::poll_jobs)
- Place decodes, flattens and resizes in slices (PlaceSteps), reading a path
  and keeping the frame, memory gate and typed memory-budget errors main has
- The web build places dropped and picked files a slice per frame, with a
  bounded place inbox
- A measurement of the stepped place; docs for jobs without threads
2026-11-06 08:51:17 +05:30
David MannandClaude Opus 5.5 99b93f82da Batch 18 (CodeRabbit nitpicks): crop test checks the active layer's covered pixels; Esc test goes through the shortcut handler
- #11458: the straight-crop rows also check that the active layer's pixels
  inside the old canvas are the plain crop's, so a fill that recolours them
  fails.
- #11295: the Esc case sends the key through shortcuts::handle instead of
  calling cancel directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:04:26 +01:00
yoriswind d58701ddff Merge current main into the Actions preservation candidate 2026-11-05 18:31:30 -08:00
yoriswind 84c41c5f10 Limit Actions panel changes to the five reviewed commands 2026-11-05 17:13:15 -08:00
David Mann d563b3100b Merge commit '9bef3b2dc8b84c1b6cefc8ce0dc2b01d089cd9e8' into HEAD
# Conflicts:
#	crates/engine/tests/it/svg_smart_object.rs
2026-11-06 01:46:48 +01:00
David Mann 1d053f5c2c Merge PR #11495: Actions: play recorded Stack Modes and Video Frame events 2026-11-06 00:28:47 +01:00
David Mann 1d5c69dda4 Merge PR #11458: Crop: fill the active layer and Background with Content-Aware Fill 2026-11-06 00:28:41 +01:00
David Mann f96e77e794 Merge PR #11553: Actions: replay recorded Perspective Warp steps 2026-11-06 00:28:38 +01:00
e55e2f3577 Place decodes and fits in the background: dropping a large file no longer freezes the window (#10147)
* 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>
2026-11-05 22:49:52 +01:00
yoriswind 8bc5399652 Keep unknown Stack Mode None descriptors inert 2026-11-05 12:57:30 -08:00
yoriswind 19ac2452a0 Merge Batch 17 while preserving Crop fill and Artboard sizing 2026-11-05 09:15:36 -08:00
yoriswind 8a126888f3 Merge upstream main after integration batch 17 2026-11-05 09:09:02 -08:00
yoriswind 9f393ebeb5 Require the null class for edited Stack Mode None provenance 2026-11-05 08:50:31 -08:00
yoriswind b6bb43bc19 Handle edited Stack Modes and cap video frame growth 2026-11-05 08:48:40 -08:00
yoriswind fbccaaeabb style(actions): apply Perspective Warp formatter 2026-11-05 08:40:04 -08:00
yoriswind 3feae0e0b6 Actions: map recorded Perspective Warp planes 2026-11-05 08:36:06 -08:00
yoriswind 05d3c0bf27 Support recorded Smart Object Stack Modes and video frame edits 2026-11-05 06:24:06 -08:00
yoriswind 04a3d0d295 fix(crop): bound the widened sampling read 2026-11-05 05:43:56 -08:00
yoriswind add3c72f91 fix(crop): keep Background fill for a donorless active layer 2026-11-05 05:37:55 -08:00
yoriswind 337794eadc test(crop): size turned controls for the minimum warp budget 2026-11-05 05:36:45 -08:00
David Mann f162c19e81 Merge remote-tracking branch 'origin/main' into integration-batch-17
# Conflicts:
#	crates/ui-egui/src/control/dispatch.rs
#	crates/ui-egui/src/control/params.rs
2026-11-05 12:44:02 +01:00
Khawar Zamman Wani e3ecd73569 feat(frame): rework the Frame tool's selection, handles and placement (#8920)
Thanks @wanikhawar — merging the Frame Tool rework.

Summary: Frame Tool selection/handles/placement now distinguish frame vs image (border / click / double-click and Layers thumbnails), with independent transforms, shape variants, Properties/options-bar stroke and fit commands, Convert to Frame, CLI/MCP `layer.frame.*` commands, native `.pcraft` persistence, and PSD export via editable groups + `pcFr` metadata (not Photoshop's native frame type). Tests cover selection, transforms, fitting, locks/hostile geometry, and native/PSD round-trips.
2026-11-05 12:39:02 +01:00
David MannandClaude Opus 5.5 16000b01ef Address CodeRabbit review: batch 17 findings
Engine: droplet dependency capture skips disabled steps; a nested Batch
that was cancelled or could not write its error log fails the caller;
runDroplet forwards overrideOpen; actions.rename follows named Batch
steps; Batch steps inside a script count against MAX_SCRIPT_STEPS;
output claims compare destination identity; Save and Close never
replaces a read-only source. ATN: Md must be a BlnM enumeration,
adjustment-layer names must round-trip, Calculations exports a missing
blending as Multiply, Apply Image refuses unnamed-layer transparency.
Filters: Shape Blur records its resolved geometry, reserves its kernel
memory first, and reports a preparation failure as an error, not a
cancel; Crop keeps an artboard preset when the size is unchanged and
fits the board on a turned crop.

Codecs/cms/algo: zero-axis FITS image HDUs are empty; a GIF walk that
breaks off before the trailer fails closed; two-value .3dl shaper rows
are applied; fragmented custom kernels are refused and their work polls
cancellation.

UI: Conditional branches play through panel playback; paused actions
refuse to resume after being replaced; Playback Options OK validates
its fields; transform double-click ignores a hidden pivot; path boxes
snap to a stationary selection; modal blocking uses the effective tool;
a picker-consumed release clears snap lines and ends a Move drag; the
Crop preset control shows Selection and checks only it; Crop box undo
restores frame_from_selection; Bosnian fill labels.

Tests: timing asserts moved to an ignored test, plus the review's
coverage nitpicks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 11:37:38 +01:00
yoriswind 1de6c9e2c5 Find active layer donors beyond a turned crop corner window 2026-11-05 01:29:48 -08:00
yoriswind 224dcdc936 Fix content-aware crop targets and history labels 2026-11-05 01:29:48 -08:00
David Mann 5385ebd95b Merge PR #10788: Support recorded dialog filters, Calculations and Batch naming
# Conflicts:
#	crates/engine/src/cmd/actions_cmds.rs
#	crates/engine/src/cmd/automate_cmds.rs
#	crates/engine/src/cmd/file_cmds.rs
#	crates/engine/src/cmd/file_cmds/batch_run.rs
#	crates/engine/src/cmd/file_cmds/tests.rs
#	crates/engine/tests/it/main.rs
#	crates/ui-egui/src/panels/actions.rs
2026-11-05 05:19:44 +01:00
30b199f8df Port #8659: keep name, blend mode and clipping on adjustment-layer Make steps
An adjustment layer's Make step now loads its `Nm  `, `Md  ` and `Grup`
keys as the command's `name`, `mode` and `clipToPrevious` params and saves
them back. An unreadable value keeps the step as an unsupported kept step;
`layer.newAdjustmentLayer.*` validates the new params like New Layer and
clips through the clip-group rules. Fixes the remainder of #8384.

Co-Authored-By: bommerts <44821497+bommerts@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 04:35:32 +01:00
8d34370bcf Port #8111: the Crop tool fits a canvas-sized artboard to its frame
A straight Crop tool crop (image.crop with an explicit rectangle) of a
document whose only artboard covers the whole canvas now fits that board
to the new canvas and clears its size preset. Before, the board kept its
old size and hung past the cropped canvas.

Measured in the reference application: its Crop tool in an artboard
document edits the artboard ("Edit Artboard": the board takes the frame,
content stays where it is), so the visible result matches. Image > Crop
with a selection does nothing there, Image > Trim keeps the board's
size, and a turned crop is impossible with artboards.

Left out of the original PR: the fit on selection crops, Trim and turned
crops (they differ from the reference application), so crop_doc and
Export Layers to Files are unchanged; the printer-query commits
(superseded on main) and the shapes.rs hunk (already on main).

Co-Authored-By: durtyrobbin <76844303+durtyrobbin@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 04:00:14 +01:00
yoriswind 83861f6862 Preserve DDS subresources and recorded filter representations 2026-11-04 17:12:28 -08:00
yoriswind 067cef6543 fix: preserve DDS slices and recorded Shape Blur metadata 2026-11-04 16:54:35 -08:00
yoriswind a27de5e30d fix: replace stale Smart Filter shape selectors 2026-11-04 16:06:21 -08:00
yoriswind 6c831b7569 fix: retain LUT shapers and resolve edited Shape Blur geometry 2026-11-04 12:34:44 -08:00
yoriswind 1720af269d Merge current main while preserving recorded Batch safeguards 2026-11-04 10:47:01 -08:00
yoriswind 0769620468 Keep unsupported Shape Blur origin in preservation regression 2026-11-04 10:44:31 -08:00
David MannandClaude Opus 5.5 642bcf6229 Fix-up #10986 with #10965: a play that changes nothing adds no history entry
With #10965 an action play is one history entry, and a play that leaves the
document unchanged adds none (#10944). The Current Layer fill from the uniform
layer alone rewrites the same pixels, so the test expects an entry, and checks
undo and redo, only when the document changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 15:45:35 +01:00
David Mann cb323e9aea Merge PR #10965: Group action playback into one history state 2026-11-04 14:51:18 +01:00
David Mann aac944a315 Merge PR #11223: Actions: map supported classic Gradient recordings
# Conflicts:
#	crates/engine/tests/it/main.rs
2026-11-04 14:51:00 +01:00
David Mann fd736f7ddc Merge PR #10986: Actions: map recorded Content-Aware Fill settings 2026-11-04 14:50:49 +01:00
David Mann a7f34dfa9f Merge PR #11222: Actions: support recorded Type Create Work Path 2026-11-04 14:50:47 +01:00
yoriswind a629a725f0 Preserve source data and diagnostics during Batch saves 2026-11-04 05:48:09 -08:00
skylar taylor-barrick e88adf20a0 Merge pull request #10921 from RickiNano/fix/show-effect-cache-pref
Preferences: show Effect Cache, which the engine reads (#204)
2026-11-04 12:36:56 +01:00
yoriswind 6855fb68fd Document Type Work Path mapping and regression oracles 2026-11-03 22:06:23 -08:00
yoriswind 85fc78bb64 Merge current main into recorded Actions dialog support 2026-11-03 21:55:00 -08:00
yoriswind 9efa1735ee Select an older text layer in recorded path playback tests 2026-11-03 20:05:36 -08:00
yoriswind 98369cfcf0 Remove the unused Gradient integration test import 2026-11-03 19:57:59 -08:00
yoriswind f135134eb3 Accept recorded Gradient descriptor classes and cover boundaries 2026-11-03 19:52:22 -08:00