Commit Graph

2166 Commits

Author SHA1 Message Date
David Mann 523f1f06bc
Preferences › Interface: Photoshop's Appearance / Presentation / Options layout (#2532) (#2589)
* Preferences › Interface: Photoshop's Appearance / Presentation / Options layout (#2532)

Replace the ~300 px theme preview cards with Color Theme swatches (a light
and a dark row, since we follow the system appearance) and group the page
like Photoshop: Appearance (mode, themes, canvas colour and border),
Presentation (UI language, font size, scaling) and Options (checkboxes).
At 1000×750 the language now shows without scrolling, in Photoshop's
place rather than moved to the top.

The swatch rows come from LIGHT_THEME_OPTIONS / DARK_THEME_OPTIONS, so
Breeze Light and Breeze Dark show up. Each swatch keeps the favourite star
(#2445) as a badge on its corner, shown on hover and kept for a favourite,
with the same "Add to favorites: <theme>" / "Remove from favorites: <theme>"
labels. Preferences search filters the grouped page: rows that don't match
are hidden and a group left empty is skipped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Preferences: rustfmt the grouped Interface page

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Tests: 32-bit destructive Levels keep the HDR range (main is red since #2592)

#2592 made float Levels keep values outside 0..1 and updated compose's
levels_dont_clip_in_32_bit, but the engine-side copy still expected 0 and 255
at 32 bits, so test (ubuntu/windows) and corpus tests fail on main.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 1ebaf7612e9ee013399cf3b4551f4094f63e2f04)

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 12:41:08 -04:00
Auros 2e242bde67
Fix Export As freeze on large layered PSDs (#5104)
Co-authored-by: luy <luy@qcplay.com>
2026-10-13 12:41:01 -04:00
David Mann 945e3e0ee4 Merge origin/main into fix/secondary-shortcuts
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 18:40:24 +02:00
baz 1e916a4e4a
Pen: Ctrl/Cmd edits the path being drawn in place (#4022) (#4526)
Ctrl/Cmd-pressing an anchor, a shown handle or a segment of the Pen (or
Curvature Pen) path in progress now edits it like Direct Selection does,
and drawing carries on from its last anchor once Ctrl/Cmd is released,
as in Photoshop. A Ctrl/Cmd-press anywhere else still ends the path.

The path in progress is a new Direct Selection candidate, PathRef::Pen,
built from ui.pen; its edits apply to ui.pen directly (no command, no
history step) since the path isn't in the document until it's finished.
The Add/Delete Anchor Point tools handle it the same way.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:34:23 -04:00
jonathanwxh-cell 907752daf2
Give Image Statistics a source-file dialog and stack mode selector (#4778)
* Give Image Statistics a source-file dialog and stack mode selector

* Keep stack sources in vertical rows and translate the mode label

* Place the new label alongside stack-mode translations

---------

Co-authored-by: jonathnwxh <258340642+jonathanwxh-cell@users.noreply.github.com>
2026-10-13 12:34:16 -04:00
Gert Pellin - GPE d3d86da130
Select › Color Range: Skin Tones (#4473)
select.colorRange takes {"select": "skinTones"}: a soft skin-tone model
in the YCbCr chroma plane (an ellipse along the skin run of Chai & Ngan,
1999) with a luminance gate, so near-black and near-white pixels drop
out. Fuzziness widens or narrows it as it does for Sampled Colors; the
selection modes, Invert and Sample All Layers work as for the other
presets. The dialog lists Skin Tones with Fuzziness enabled.

Detect Faces needs a face detector, which there is none of yet:
detectFaces: true is refused with a message instead of being ignored.

Fixes #4455
2026-10-13 12:34:04 -04:00
F4LCON 96c0241b26
Distort: a quad dragged past the horizon draws only its front side, in the preview and the result (#4863) (#4870) 2026-10-13 12:33:53 -04:00
Tarek Mohamed c4f0b8aa8b
fix(compose): redraw shapes crossing canvas bounds and include vector bounds in damage (#3946) (#4493) 2026-10-13 12:33:47 -04:00
Marco Arnulfo e4f005d3dc
Palette PNGs open in Indexed Color mode with their colour table (part of #4804) (#4817) 2026-10-13 12:33:39 -04:00
Valentin Klein efb67fc826
Text: binary-search the run lookup and probe smcp once per layout (#4430) (#4432)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:33:33 -04:00
Ikki Nishihara 66e07cbf79
fix(gpu): refresh patterns when defaults or formats change (#5013)
Co-authored-by: haranishi <223786623+haranishi@users.noreply.github.com>
2026-10-13 12:33:27 -04:00
FinnNk 752f611264
perf(compose): the shape stroke split cache keeps to a byte budget and empties on Purge (#4530) (#4774)
shape_split caches a stroked shape's fill and stroke rendered over the
canvas, for shapes with clipped layers: up to 32 entries of two
canvas-sized surfaces each, with no byte cap (several GB at 24 MP) and
nothing in Edit › Purge › All to clear it.

It now evicts least recently used entries until a new one fits both
the 32-entry cap and a 256 MiB pixel budget (an entry larger than the
whole budget is used and not kept), and Purge › All clears it as
"shape stroke cache", reporting the bytes like the other caches.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:33:21 -04:00
MrCloudy2 5f2c23e142
Filters: Photoshop's Blur More kernel, Find Edges strength and Polar Coordinates direction (#4652)
Measured against Photoshop 27.11 on a test chart: Blur More uses the
[1 2 1; 2 2 2; 1 2 1]/14 kernel, Find Edges the full Sobel magnitude, and
Polar Coordinates turns counter-clockwise from 12 o'clock with repeated
edges and Photoshop's sampling grid. All four now match within 2 levels.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:33:15 -04:00
FinnNk cdfec72f71
perf(ui): the Navigator draws the GPU canvas's texture instead of a CPU thumbnail (#4518) (#4701)
With the GPU canvas, the Navigator still composited the document on
the CPU on the UI thread after every edit: render_reduced_damage over
the full-resolution damage, or a full thumbnail_buffer composite when
the document has effects. On the #209 layered 20 MP document that was
126–137 ms after a small opacity edit and about 700 ms for a
full-canvas layer, against 3.4 ms for the canvas itself.

While the main canvas shows the plain document on the GPU canvas, the
Navigator now paints that same texture through the canvas's own
shader (GpuCanvas::paint) at its size: no composite, no readback, with
the display transform the canvas uses. Everywhere else (a CPU canvas,
a flipped view, an adjustment proxy or preview) it keeps the CPU
thumbnail. Until the canvas has drawn a new document it waits up to
three frames rather than build a CPU thumbnail it would use once.

The preview is resampled through the display mips instead of the CPU
thumbnail's area sampling: thin lines average to even grey instead of
aliasing, and edges are a little softer.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:29:25 -04:00
Dan Hiorns 13697cf5f5
Preset panels: the footer stays in view in a short dock group (#4790) (#4824)
The Swatches, Gradients and Patterns browsers capped their list with a
fixed allowance for the footer (30 or 40 px) and kept a minimum list
height (60 or 90 px, and egui's 64 px minimum for a scroll area). In a
short dock group the list took that room anyway and pushed the footer
(size slider, New Group, New, Delete) out of view: Swatches' slider was
cut in half, Patterns' footer was hidden entirely.

The shared browser now measures its footer and gives the list only the
height left after it, so the list scrolls and the footer stays visible,
as in Photoshop.

Fixes #4790

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:29:19 -04:00
JGF 033ec991c2
fix(ui): show a magnifier cursor for the Zoom tool on Windows (#3735) (#3783)
winit maps CursorIcon::ZoomIn/ZoomOut to the plain arrow on Windows, so
the Zoom tool showed no cursor feedback there. Draw the magnifier (plus,
or minus while Alt zooms out) as an OS cursor bitmap, like the Hand
tool's #2196 fix; macOS and Linux keep their stock zoom cursors. Camera
Raw's preview zoom uses it too.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:29:13 -04:00
Dan Hiorns ef2905ea8e
Control: list and answer the unsaved-changes prompt (#4920) (#4924)
When a document with unsaved changes was closed, reverted, or the app was
asked to quit, the Save / Don't Save / Cancel prompt showed in the window
but not in ui.inspect, and a control client had no way to answer it: the
app stayed open until someone clicked.

ui.inspect now lists the prompt among its dialogs with the id "discard":
the waiting command, the document it asks about, how many are left and
the choices. ui.dialog.confirm {"dialog": "discard", "choice":
"save"|"dontSave"|"cancel"} answers it through the same code as the
buttons (one document at a time when quitting), and ui.dialog.cancel
cancels it. The automation policy sees the parked command before a save
or don't-save answer runs it.

Fixes #4920

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:24:35 -04:00
Shehan Kavishka b21956aef7
fix(ui): Match Color's preview reads the Source document (#4851) (#4886)
The filter preview runs the command in a fresh session holding only a proxy
of the edited document, so a document param such as Match Color's Source
(or Displace's map) pointed at nothing there: with another document as the
Source the preview failed and the canvas kept showing the unchanged image,
and with the first open document it matched the image to itself. OK then
applied a different result from what the dialog showed.

The preview now adds each referenced open document (as a proxy at the same
factor) to its session and points the param at it, so it shows what OK
applies.


Claude-Session: https://claude.ai/code/session_01J5ysoK8nmS7grqCY1wGvhy

Co-authored-by: Leel Wasanatha <260480244+kavishkashehan726-sudo@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:24:28 -04:00
avdyliisni9-png cd35577c45
Polygonal Lasso: drop the polygon in progress when another document becomes active (#5015)
Follow-up to #4021, which drops the polygon when another tool is selected. The polygon now also remembers the document it was started on (UiState::polygon_doc) and is dropped when another document becomes active, as the Lasso and the Magnetic Lasso already do; before, its outline showed on the other document. Adds tests that every selection tool and Move/Brush drop the polygon (#4021 tests Quick Selection only), that a document switch drops it, and that a held Space or Cmd temporary tool keeps it.

Co-authored-by: ZulejhaAvduli <269043497+avdyliisni9-png@users.noreply.github.com>
2026-10-13 12:24:22 -04:00
F4LCON 62bf7391ce
New Document: a custom background colour, from Custom… or the swatch beside the menu (#4789) (#4801)
* New Document: a custom background colour, from Custom… or the swatch beside the menu (#4789)

* New Document: test the swatch's colour for each Background Contents choice (#4789)

Co-authored-by: persi-man <69083413+persi-man@users.noreply.github.com>

---------

Co-authored-by: persi-man <69083413+persi-man@users.noreply.github.com>
2026-10-13 12:24:16 -04:00
abc2cb f4b3766b91
Smart Filters: drag a filter up or down its stack to reorder it (#4897)
In Photoshop the order of smart filters matters (the bottom one is applied
first: Unsharp Mask over a Gaussian Blur sharpens the blurred image, under it
the sharpening gets blurred), and a filter row is dragged up or down the stack
to change it. The engine already had `layer.smartFilter.move` and re-renders in
the new order, but the Layers panel had no way to reach it: a filter row could
only be dragged onto another smart object or onto Delete (#4271).

Dragging a filter row over another row of its own stack now draws an insertion
line above or below that row (the Smart Filters row: on top of the stack), and
the release runs `layer.smartFilter.move`, one undo step. The moved filter ends
up selected with its smart object active, as after a click. Drops next to the
filter's current place, or on itself, do nothing.

Tests: `smart_ui::tests::a_filter_dropped_above_or_below_a_row_lands_next_to_it`
(the index math) and `smart_filter_rows_tests::dragging_a_filter_up_or_down_its_stack_reorders_it`
(whole app: above, below, onto the Smart Filters row, selection, undo).

Co-authored-by: abc2cb <271337822+abc2cb@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:18:42 -04:00
Dan Hiorns 33d9cb6ac4
UI fonts: draw a variable CJK fallback at Regular, not Thin (#4820) (#4830)
On systems with only Noto Sans CJK's variable collection (Fedora's
google-noto-sans-cjk-vf-fonts), the UI's CJK fallback was registered at
the font's default instance, which is Thin (wght 100), so CJK labels and
layer names came out hairline next to Latin text.

A fallback face with a weight axis whose default isn't Regular is now
registered with wght 400 (clamped into the axis) through egui's
FontTweak::coords. Static faces and variable faces that already default to
Regular are unchanged.

Fixes #4820

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:18:36 -04:00
OctaNebula 026de5e2a3
fix(layers): Ctrl+Alt+G releases the clipping mask when pressed again (#4927)
Cmd/Ctrl+Alt+G only ever ran Create Clipping Mask, so pressing it on a
clipped layer did nothing. In Photoshop the Layer menu has one item that
reads Create or Release Clipping Mask with the same shortcut, so the key
toggles the clip.

The key now runs Release Clipping Mask when the layers Create would clip
are all clipped already (the selected layer, or every selected layer above
the lowest), next to the Delete key's redirect in shortcut_dispatch. The
engine commands are unchanged, so agents still get exactly what they call.

The Layer menu follows: its Create Clipping Mask slot reads Release
Clipping Mask (and runs it) with the same shortcut while the key would
release, and the separate shortcut-less Release item that sat at the
bottom of the menu is gone.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:18:28 -04:00
Dan Hiorns ad62f350e5
Symmetry: Transform Symmetry gets commit/cancel buttons and its own cursors (#4495) (#4508)
Transforming the painting symmetry could only be applied with Enter or
dropped with Esc, which a pen or touch user may have no key for, and the
canvas kept the brush outline although a press there doesn't paint.

While the transform is open, the options bar now shows "Transform
Symmetry" with commit and cancel buttons, like Free Transform's bar. The
canvas shows the move cursor over the centre, the rotate cursor over the
rotation handle and the arrow elsewhere.

Test: transform_has_commit_and_cancel_buttons_and_its_own_cursors.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:18:21 -04:00
Michael Higgins c72dda1914
Assign Profile: list only profiles of the document's colour mode (#4951) (#5020)
The profile menu offered every built-in and installed profile, and picking
one of another colour space only produced "profile is Rgb; the document is
Cmyk" in the status bar. The menu now lists the profiles the command accepts
for the document's mode, and a remembered choice that doesn't fit falls back
to the working space.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:11:56 -04:00
imSlicedBread a0627311ab
Fix window dragging with modal dialogs (#4913) 2026-10-13 12:11:50 -04:00
Arif Uğur Çelik f43d019a72
Brush Settings: use an amount slider for Hue Jitter (#4874)
Use the shared percentage row so the jitter amount does not look like a hue selection. Cover the rendered themed track, numeric and pointer edits, neighboring settings and engine journal replay.

Addresses the Hue Jitter appearance item in #3825; other assessment items remain open.

Co-authored-by: augrclk <217665348+augrclk@users.noreply.github.com>
Co-authored-by: GPT-6 <noreply@openai.com>
2026-10-13 12:11:44 -04:00
Dan Hiorns 05d361a367
Shortcuts: ⌥⇧⌘N makes a new layer without the dialog (#4794) (#4807)
⇧⌘N opens the New Layer dialog, as Layer › New › Layer… does in Photoshop.
Photoshop's companion shortcut, the same keys with ⌥ (Ctrl+Alt+Shift+N on
Windows and Linux), makes the layer at once; PhotoCraft didn't handle it,
so there was no way to get 0.7.0's dialog-free behaviour from the keyboard.

New Layer's shortcut with ⌥ added now runs layer.new.layer directly. It
follows a rebound New Layer shortcut, and a command bound to that key
itself keeps it.

Fixes #4794

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:11:37 -04:00
Dan Hiorns e4d281eb20
Brushes: preset card size numbers stay clear of the tips (#4454) (#4485)
In the Brush Preset picker's cards the tip thumbnail grew to 44.8 pt in a
42 pt cell while the size number was anchored to the cell's bottom, so
the number of any medium or large brush (Hard Round's 30, Soft Round's
45) was drawn under the tip and couldn't be read.

card_tip_rect now keeps a band for the number at the bottom of the cell
and fits the tip above it, still scaled by the preset's thumb_scale so
big brushes read bigger than small ones. Compact cards (no number) are
unchanged.

Test: card_tips_never_cover_their_size_number checks every footer scale
that shows numbers, in all three card kinds.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:11:31 -04:00
Marco Arnulfo 2ca12e17b5
Direct Selection: arrow keys nudge the selected anchors (fixes #4486) (#4500) 2026-10-13 12:11:24 -04:00
FinnNk 33728243fb
perf(gpu): closing a document frees what the compositor holds for it (#4529) (#4772)
GpuCanvas::retain called forget_doc only for documents still in its
texture map. A document whose entry had been dropped earlier (texture
creation failed, a fresh render failed after uploading, or the canvas
outgrew its budget after Canvas Size) kept its resident pages, effect
maps and lower-stack composite after it was closed, until another
document pushed the budgets over; with no other GPU document, for good.

Compositor::retain_docs forgets every document the caller doesn't list
as open, whatever the texture map says, and retain calls it each time.
The open documents' ids, their preview ids and the adjustment proxies
are already in that list, so nothing in use is dropped.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:07:27 -04:00
deadmeu 533b9a1c62
perf(raster): moving a layer no longer stores tiles of only the default pixel (#4844)
Surface::translated, under every layer move and the Move drag preview, allocated
every target tile that a moved source tile reached. For a move that isn't a whole
number of tiles, the transparent margins of a layer's edge tiles landed on target
tiles of their own, and those were stored though they hold only the default pixel
(256 KB each at 8-bit RGBA). #4414's shared uniform tiles were also stored when
their value was the default. Moving two 300 px blocks by (100, 56) left 10 of 18
stored tiles empty; nudging back and forth kept adding more.

A target that ends up holding only the default pixel is no longer stored, as
prune() would drop it. A copied tile is compared row by row with a row of the
default pixel after the copy (one memcmp per row; a tile with content stops at
its first row), and a shared uniform tile of the default value is skipped. Moves
by whole tiles still re-share the existing tiles unchanged.

Release, 24 cores, cargo xtask perf --quick (perf_scenarios, p50, HEAD vs this,
two runs each): move layer on 16-bit 15000x10000 + refresh 5.3 -> 3.9 ms; move
layer on 32-bit 20 layers + refresh 11.9 -> 5.9 ms; the other Move rows within
noise. translated() alone on 36 MP: full layer unchanged (27.0 -> 27.6 ms RGBA8);
40 sparse blocks 11.8 -> 10.6 ms RGBA8, 44.0 -> 39 ms RGBA16, 308 -> 190 tiles.

The new test covers RGBA8, RGBA16, RGBA32F and GRAY8 over a zero and a non-zero
default pixel, and both paths; it fails on the old code.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:07:20 -04:00
Timothy Daly f1233bb43a
io: a tagged CMYK file's merged image reads through its own profile (#4948)
merged_composite showed a CMYK merged image through the built-in coated
profile, while the compositor reads the file's layers through the
embedded one. Every oracle comparison of a tagged CMYK file therefore
measured two different profiles. psd-tools' CMYK files were 88-100% off
even with nothing to adjust: colormodes/4x4_8bit_cmyk.psd, a plain
image, was 100% off.

It now converts inside the document's CMYK space (compose::cmyk_space).
The test reads the merged inks back and checks them against the embedded
and built-in conversions.

psd-tools, bad pixels (pass count unchanged at 213/309):
- invert_cmyk: 98% -> 15%
- levels_cmyk: 95% -> 14%
- curves_cmyk: 98% -> 37%
- threshold_cmyk: 65% -> 7%
- posterize_16bits_cmyk: 88% -> 13%
- 4x4_8bit_cmyk: 100% -> 6%

With #4945's ink compositing, invert_cmyk and
brightnesscontrast_legacy_cmyk pass (215/309).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:07:14 -04:00
Gert Pellin - GPE 7b0dbf182b
PNG: a whole-ppi pHYs reads back whole (300 ppi stays 300) (#4857)
pHYs holds whole pixels per metre, so 300 ppi is stored as 11811 and
read back as 299.9994 (72 as 72.009). The ppi read is now the whole
number that rounds to the stored value when there is one, as Photoshop
reads it; other values stay as they are.

Fixes #4855
2026-10-13 12:07:08 -04:00
Nigel Ihza Firdausy 5320cecb6d
fix(adjust): preserve midtone luminosity with multiple sliders (#4941) (#4990) 2026-10-13 12:07:03 -04:00
Dan Hiorns 87aed12d62
Brush import: Dual Brush spacing comes from its tip (#4809) (#4889)
Photoshop CC brush presets store the Dual Brush spacing the panel shows in
the dual tip (dualBrush > Brsh > Spcn), and also write a Spcn of 100 % on
the dualBrush object beside it. The importer read that outer value last,
so every dual brush came in at 100 % spacing (the reporter's 10 %, 18 %
and 24 % presets all did), which changes the stroke a lot.

The tip's spacing now wins; the outer value only stands in for a tip
without one.

Fixes part 1 of #4809

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:06:56 -04:00
F4LCON 1168a9dd73
Pen: a new path joins the selected path instead of replacing the Work Path (#4721) (#4730) 2026-10-13 12:03:43 -04:00
Nigel Ihza Firdausy 625141c2ad
fix(ui): display uppercase hex values in the color picker (#4859)
* fix(ui): show uppercase RGB hex values in shared color picker

* test(text): expect uppercase hex in text style color picker

* fix(ui): uppercase displayed hex without changing color storage

* test(text): keep color serialization independent of picker display casing
2026-10-13 12:03:37 -04:00
F4LCON 5adba14cd6
Navigator: one zoom row as in Photoshop, the percentage, Zoom Out, the slider and Zoom In (#4840) (#4854) 2026-10-13 12:03:30 -04:00
Valentin Klein cca24dd0d8
Type options: the wheel over the font menu steps through the families (#3350) (#3524)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:03:23 -04:00
jonathanwxh-cell f20605219e
Keep applied guide layouts visible after preview closes (#5084)
Co-authored-by: jonathnwxh <258340642+jonathanwxh-cell@users.noreply.github.com>
2026-10-13 12:03:16 -04:00
Nigel Ihza Firdausy 35710a94ad
Fix: native gesture fallback dedupe (#5080)
* fix(input): avoid double-applying native pinch during legacy fallback

* test(input): cover native trackpad rotation and preference gating
2026-10-13 12:03:11 -04:00
Alon 77d3478df1
fix(gradient): options-bar Opacity updates the live gradient layer (#5012) (#5045) 2026-10-13 12:03:05 -04:00
Marco Arnulfo 997406a584
Layer Style applies an open Free Transform first, so its preview shows (fixes #4821) (#4835) 2026-10-13 12:02:58 -04:00
Marco Arnulfo 78b70df227
Canvas: the CPU canvas shows crisp pixels when zoomed in (fixes #4810) (#4825) 2026-10-13 12:02:51 -04:00
Marco Arnulfo 665cb581ad
Smart Filters: Delete removes the selected filter, not its smart object (part of #4751) (#4764) 2026-10-13 12:02:44 -04:00
Ivan · VanTan eae87bacfa
i18n(ru): translate dynamic selection, theme and measurement labels (#4838) 2026-10-13 12:02:38 -04:00
Sir Starch 2ec1c8c0aa
Themes: default light theme to Pro Light to preserve the Pro layout (#5016) (#5029)
When appearance mode was toggled between dark and light with default
settings, PhotoCraft switched from Pro Medium (Pro layout) to Studio Light
(Studio layout), altering the UI and displaying a Fit button in the status
bar.

Now that the Photoshop Pro light brightness levels exist (#2661), default
the saved light theme to Pro Light so the Pro interface layout and status
bar are preserved when toggling appearance. Also map the "light" alias to
Pro Light and list the Pro options first under Light Theme preferences.

Fixes #5016.
2026-10-13 12:02:32 -04:00
Dan Hiorns 334d378f0f
Toolbar: clicking a tool's button again closes its open flyout (#4932) (#4937)
A right-click (or long press) on a tool button opens the flyout of the
tools grouped with it. Any press outside the flyout closed it, but the
press-outside check leaves out the tool button itself, so clicking that
button again, with either mouse button, left the flyout open.

A click on the button of its open flyout now closes it, as in Photoshop:
a right-click just closes it, a left click closes it and picks the tool
as any click does. The release that ends the long press that opened the
flyout still keeps it open.

Fixes #4932

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:02:26 -04:00
F4LCON 3d54e8cd68
Alerts: Enter is OK, but not the Enter that raised the alert (#4872) (#4880) 2026-10-13 12:02:12 -04:00