Commit Graph
8998 Commits
Author SHA1 Message Date
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 1a7b62a878 Compare CLI Batch output identity across native path separators 2026-11-04 11:39:13 -08:00
yoriswind 4f407b81c5 Preserve CLI run continuation after direct Batch file errors 2026-11-04 11:15:56 -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 Mann 8e82c0e728 Merge pull request #11278 from davidmann4/integration-batch-16
Integration batch 16: 9 epic PRs on main
2026-11-04 19:20:54 +01:00
David MannandClaude Opus 5.5 14f6ace170 Fix-up #11243 (review): Free Transform a Copy of a targeted mask still copies
The linked-layer path (no copy, the link group's box) applies only when the
layer's own pixels are the target; an unlinked layer mask targeted on a linked
layer is copied as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 17:33:00 +01:00
David MannandClaude Opus 5.5 c144e36d9c Fix-up #11077 (review): say that pixels past the canvas count for Empty
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 17:32:59 +01:00
David MannandClaude Opus 5.5 533cf55ef5 Fix-up #11235 (review): a filter already on at the row's first draw deselects
With no criteria kept yet (the row's first draw, e.g. after ui.set while the
panel was closed), a filter that is on counts as applied.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 17:32:59 +01:00
David MannandClaude Opus 5.5 1a9be65e0f Fix-up #10965 (review): a continuation resumes once; a layer target checks its receiver
A kept clone of a paused action's continuation could reopen a scope that had
already resumed and finished; every clone now shares one resumed mark. A dialog
paused on a document target (Quick Mask or an alpha channel) and switched to a
layer target now checks the layer that was active at the pause.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 17:32:59 +01:00
David MannandClaude Opus 5.5 a8b69338da Fix-up #11243: Free Transform a Copy of a linked layer makes no copy
Measured in the reference application: Ctrl+Alt+T on a linked layer without
a selection makes no copy; the box frames and moves the whole link group, and
History shows one Free Transform. An unlinked layer still gets its copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 16:33:00 +01:00
David Mann ff7d36fe4b Merge the batch branch (closing merge of #6647) into the fix-ups 2026-11-04 15:46:08 +01:00
David MannandClaude Opus 5.5 524826e9fc Fix-up #10396: Esc in crop_beyond_canvas hides the frame
Since #10396 Esc hides the crop frame until the next press (#10370), so the
test expects no frame after Esc instead of a new default one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 15:45:35 +01: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 MannandClaude Opus 5.5 8bc0179235 Fix-up #11243: a lone copy of a linked layer joins its link group
Measured in the reference application: Duplicate and Layer via Copy of one
linked layer put the copy in the original's link group. Copies of several
layers of one group still get a group of their own, and a copy that is the
only one from its group among several copied layers is still unlinked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 15:45:35 +01:00
David MannandClaude Opus 5.5 31a9b91913 Merge PR #6647 (closing): its zoom field work landed with #10145; changes reverted, tree unchanged
Merged with the ours strategy so GitHub closes #6647 as merged. Everything
it carries is either on main already (via integration batch #10145) or,
for the later contributors entry, left out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 15:44:59 +01:00
yoriswind 4c17ccef19 test: import Action in the split Batch scenarios 2026-11-04 06:02:40 -08:00
David Mann cb323e9aea Merge PR #10965: Group action playback into one history state 2026-11-04 14:51:18 +01:00
David Mann d7e2bbe4a4 Merge PR #11077: Layers panel: filter by layer attribute (#10881)
# Conflicts:
#	crates/ui-egui/src/panels/layer_filter_ui.rs
#	docs/control-protocol.md
2026-11-04 14:51:17 +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 e8bc140aa2 Merge PR #11243: Free Transform: linked layers transform together (#11217) 2026-11-04 14:50:48 +01:00
David Mann a7f34dfa9f Merge PR #11222: Actions: support recorded Type Create Work Path 2026-11-04 14:50:47 +01:00
David Mann 3ea385cef3 Merge PR #11017: Layers filter: fill layers match no Kind button, and the Mode list has no Pass Through (#10878) 2026-11-04 14:50:46 +01:00
David Mann 6a989bacdc Merge PR #11235: Layers panel: applying a filter deselects the layers it hides (#10879) 2026-11-04 14:50:45 +01:00
David Mann 8f9cc7bbf5 Merge PR #10396: Crop: Esc hides the crop frame until the next press (#10370) 2026-11-04 14:50:44 +01:00
yoriswind a629a725f0 Preserve source data and diagnostics during Batch saves 2026-11-04 05:48:09 -08:00
FredApps 5617e00ca0 Merge pull request #11168 from hnoerenberg/fix/image-assets-save-errors-11117
fix(ui): a save that failed some Image Assets reports which outputs (#11117)
2026-11-04 14:35:55 +01:00
David Mann 2c68cc6b95 Merge pull request #11203 from davidmann4/integration-batch-15
Integration batch 15: Crop, Free Transform and Actions epic PRs
2026-11-04 14:18:54 +01:00
Josias Eli Rodriguez f1419f6d87 test(review): assert originals keep their group in the paired copy-drag test (#11217) 2026-11-04 07:16:30 -06:00
FredApps be3f632402 test: format save hook regression 2026-11-04 13:58:19 +01:00
FredApps 01ff0e2974 Merge pull request #8705 from the-unknown/feat/lens-flare-look
feat(filters): Lens Flare looks like Photoshop's (SSIM 0.97–0.995 per lens)
2026-11-04 13:56:53 +01:00
yoriswind e2d03afef0 test: split nested Batch scenarios for strict lint 2026-11-04 04:55:22 -08:00
Codex 9fdcbf93c2 test: cover asset failure after save script shifts tabs 2026-11-04 13:48:59 +01:00
FredApps ec549530b8 Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	crates/ui-egui/src/app/files.rs
2026-11-04 13:44:14 +01:00
FredApps 66a0853024 Merge pull request #11244 from hnoerenberg/fix/assets-after-script-close-11121
fix(assets): bind post-save generation to the saved document's identity
2026-11-04 13:42:57 +01:00
FredApps 97ba6d16a9 Merge pull request #11189 from hnoerenberg/fix/windows-replace-recovery-11178
fix(atomic): report where the original survives when the Windows restore fails
2026-11-04 13:42:21 +01:00
Hartmut NörenbergandHartmut Nörenberg bf5c479d29 fix(layers): refuse to ungroup the sole empty layer group (#11118) (#11163)
* fix(layers): refuse to ungroup the sole empty layer group (#11118)

* fix(layers): document the ungroup guard and cover the valid empty-group case

Review follow-up: docstring on ungroup() and a control test showing an empty group that has sibling root layers still ungroups (the group simply disappears).

---------

Co-authored-by: Hartmut Nörenberg <hnoerenberg@users.noreply.github.com>
2026-11-04 13:40:06 +01:00
Josias Eli Rodriguez 91189d9244 fix(review): relink copies made by a panel copy-drag (#11217) 2026-11-04 06:30:07 -06:00
Tareq HalabyandFredApps 2472b4a46b PSD: keep stylistic sets in Txt2 for PhotoCraft-native documents (#10313)
* PSD: keep stylistic sets in Txt2 for PhotoCraft-native documents.

needs_txt2 now covers Txt2-only OpenType flags (ss01–ss20 and non-default TXT2_FEATURES). Fresh documents get a framed point-text object with full style runs so Set 1/5 round-trip on save/reopen (#10308).

* Txt2: seed fill colour and font list on PhotoCraft-native blocks.

Fresh style runs get a /53 paint dict, and an empty font list gets a CoolTypeFont entry so index 0 resolves (CodeRabbit on #10313).

* Txt2: tag SimplePaint and ensure numbered /0 on legacy blocks.

CodeRabbit: write /99 /SimplePaint on fresh /53 dicts, and create the numbered resource dictionary before pad_frames when a legacy block lacks it.

* Txt2: treat a missing stylistic-set mask as 0 when comparing styles

A style run without key 85 used to agree with any ssNN mask, so enabling
ss01 could leave the file's runs in place on save. Align with import's
default of 0. Also restore the G8 gaps note after rebasing onto main.

* style(io): rustfmt psd_kerning stylistic-sets test

* Txt2: keep Photoshop /0 stable when seeding fonts and frames

Only seed a CoolTypeFont list and inject /0/8 when the block is
PhotoCraft-native or already had those keys / needs new frames, so
unedited Photoshop Txt2 saves stay byte-identical (#2374).

* style(text): rustfmt oversized-template assert

* PSD: keep the Txt2 scaffolding to PhotoCraft-native blocks

A file's own Txt2 block (any Photoshop era) is written as before: no
numbered /0 or /0/8 frame list is injected, a layer without a template
object gets its stub, a run without /53 isn't given one, and no
minimal style base is used. Only a block PhotoCraft creates itself
(prev.is_none()) gets fresh point-text objects, minimal runs, a seeded
font list and a frame list.

Fresh objects now write one /5 paragraph run per paragraph (UTF-16
lengths, checked conversion), as edited objects are refitted.

Tests: Photoshop blocks with an empty or missing /0 get no native
scaffolding; the oversized-template test is back to main's assertion;
fresh paragraph runs; the PSD round trip checks ss01 and ss05 on every
run.

---------

Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-04 13:28:06 +01:00
yoriswind 2663628348 test: open Batch fixture documents through the registered command 2026-11-04 04:23:33 -08:00
David MannandClaude Opus 5.5 f05bb0ea9b Fix-up for #9979, #9182 and #10837: review findings on the batch
- #9979: ui.dialog.set can no longer rewrite an open field picker's __colorPicker
  marker (its OK went to the Crop shield instead of the field), and Preferences Apply
  waits for an open colour picker as OK does, so it never saves a previewed colour.
  Both have regression tests that fail without the fix.
- #9182: the stress test's PC_BUILD_ROUNDS / PC_BUILDS_PER_DEVICE fall back to the
  default for 0, which ran no builds and passed.
- #10837: the ROADMAP entry no longer says a Latin hint rules windows-1251 out; the
  hint settles a word-initial rare letter and breaks exact ties.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 13:22:51 +01:00
David MannandClaude Opus 5.5 cbc674ea9a Fix-up for #10837: score legacy names in linear time
The position checks of the codepage guesser (letters after a character, a closing !,
the Cyrillic run around a letter) rescanned the rest of the name from every non-ASCII
character, so a hostile .atn or PSD with a 64 KiB step name of one letter kept Load
Actions busy for about three minutes. Each is now found once per name; the three
measured cases take 0.03 s together, and a regression test covers them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 12:54:55 +01:00
skylar taylor-barrick 68b6dbfa79 Merge pull request #10750 from RickiNano/perf/bench-cmd-refresh-split
perf(bench): split command and refresh time; refresh like the app; stop rows timing setup
2026-11-04 12:39:54 +01: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
skylar taylor-barrick db18b9d432 Merge pull request #10802 from RickiNano/fix/props-percent-units
Properties: W/H/X/Y take a typed percentage (#10784)
2026-11-04 12:30:05 +01:00
Tareq HalabyandFredApps 4d0ecd746f Toolbar: Alt/Option-click cycles the flyout tool slot (#10301)
* Toolbar: Alt/Option-click cycles the flyout tool slot.

Matches Photoshop: plain click keeps the shown tool; Alt-click advances through the slot without opening the menu (including tools Shift+letter skips).

* Toolbar: don't fit-on-screen on rapid Alt-clicks through Hand.

Alt-click only cycles the flyout slot; exclude Alt from the Hand/Zoom double-click handlers and cover inactive-slot cycling.

* Toolbar: ignore Hand/Zoom double-click after an Alt-click.

egui pairs a plain click with a prior Alt-click as a double-click; remember the previous click's Alt so fit-on-screen and actual-pixels only run for two plain clicks.

* Toolbar: read click modifiers from the slot's pointer release.

Match DesignCraft/EffectCraft: bind release mods to the tool rect, treat any modifier as blocking Hand/Zoom double-click, and harden the Alt-cycle test by clearing i.modifiers before release.

* Toolbar: cover 1/2/3-tool Alt-click cycles and hidden-tool slots.

Addresses ReviewerA on #10301: next_slot_tool wrap cases for short flyouts, and visible_sections so Edit › Toolbar hidden tools shrink the Alt-click cycle.

* style(ui): rustfmt after rebase onto main

* Toolbar: next_slot_tool never panics on an empty slot

Index with checked arithmetic and get() (house rule: no panics on
input-derived indices); an empty slot returns the current tool. Test
added.

---------

Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-04 12:29:11 +01:00
qvest-sselsandClaude Opus 5.5 fbe918c8c9 Merge origin/main into fix/crop-esc-hide-frame-10370
Main now hides the frame after a committed crop (`hide_frame` /
`show_frame`, #10642) on the same `dismissed` state this branch added,
and keeps it hidden when the Crop tool is picked again, as measured in
Photoshop. Esc now uses that state: `dismiss` is `cancel` then
`hide_frame`, so after Esc picking the tool again also keeps the frame
hidden, and only a press brings it back. The Esc test follows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 12:06:27 +01:00
David Mann 16192b6604 Merge PR #11220: Crop: centred 48-point grid while turning 2026-11-04 12:05:48 +01:00