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>
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>
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>
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>
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>
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>
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>
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>
* 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>
* 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>
- #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>
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>
* 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>
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>