Commit Graph
2265 Commits
Author SHA1 Message Date
Vlad Grankovsky d9400a7cb8 Merge upstream main 048ae7977 into curves follow-up 2026-11-07 01:41:38 +01:00
Vlad Grankovsky 283de2c506 Merge upstream main 8df2b7a2e into curves follow-up 2026-11-07 01:27:10 +01:00
David Mann 927c63d394 Merge pull request #11022 from Hamza0101/fix/crop-overlay-and-fill-defaults
Crop: Always Show Overlay by default, Fill resets on another open document, and an untouched frame shows only itself (#10894, #10930)
2026-11-07 01:11:21 +01:00
David Mann 6b0f7762e1 Merge pull request #11671 from davidmann4/integration-batch-20
Integration batch 20: 7 i18n PRs (Thai, Hebrew, Urdu, Tamil, Azerbaijani, Romanian, Korean)
2026-11-06 22:49:42 +01:00
David Mann fd890eaca4 Merge pull request #11669 from davidmann4/feat/crop-task-bar-10890
Crop: Contextual Task Bar under the crop frame, as a reusable task-bar widget (#10890)
2026-11-06 22:49:21 +01:00
David Mann 7ecfccbd64 Merge pull request #11643 from davidmann4/integration-batch-19
Integration batch 19: epic PRs (WIP)
2026-11-06 22:48:55 +01:00
David MannandClaude Opus 5.5 e078c560ec Address CodeRabbit review: task bar tile, inspect and ui.set merge
- Draw the Crop task bar only on the active document's tile: a click into
  another tile activates its document mid-pass, and the tile drawn after it
  put the new frame's bar on itself for that frame.
- ui.inspect reports the bar hidden (and no rect) as soon as it can't show,
  not only after the next draw.
- ui.set merges panels.task_bar field by field: {"at": [x, y]} keeps a pin,
  {"pinned": true} keeps a dragged place; unknown nested fields are refused.
- Tests for each (each fails with its fix reverted), plus the task bar's
  preset dropdown picking 1 : 1 in sync with the options bar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 19:41:21 +01:00
David MannandClaude Opus 5.5 5d5519dcac Regenerate docs/scorecard.md after merging main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 19:41:20 +01:00
David Mann d1d913e7e6 Merge remote-tracking branch 'origin/main' into feat/crop-task-bar-10890 2026-11-06 19:24:17 +01:00
David Mann 670fa8b5f1 Merge remote-tracking branch 'origin/main' into integration-batch-20
# Conflicts:
#	crates/ui-egui/src/prefs/prefs_ui/fields.rs
2026-11-06 19:01:38 +01:00
David MannandClaude Opus 5.5 af0ae88bad Batch: drop #9876 (New Guide unit dropdown) from the batch
The reference application's New Guide dialog has Orientation, Position
(a text field that takes typed units such as "2 cm") and Color, but no
unit dropdown; measured on 2026-11-06. Typed units already work on main,
so the PR only adds something the reference lacks.

This reverts merge 22e03d0bcb.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:54:34 +01:00
2ff8f419cb ci: run the GPU tests on lavapipe on Linux and fail if they skip (#7975)
The Linux runner has no GPU, so the GPU tests ran on Mesa llvmpipe over
GL, which can't render Rgba32Float: 57 GPU checks (50 GPU parity, 3
canvas, 2 adjustment preview parity, 2 effect-map recovery) returned
early and passed without comparing anything. A new step after Test
installs mesa-vulkan-drivers and runs the nextest `gpu` group on
lavapipe (Vulkan), reusing Test's build, and fails unless the parity
tests report the Vulkan backend and no test printed a skip.

No code change: photocraft's tests take whatever adapter wgpu returns,
software adapters included. Follows the CI half of lightcraft#1148.

Co-authored-by: FredApps <FredApps@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:44:13 +01:00
f23d173933 Add an opt-in WinTab backend for pen pressure on Windows (#11331)
* Add an opt-in WinTab backend for pen pressure on Windows

Windows Ink stays the default. Preferences > Tools > Pen Tablet has a Tablet
input dropdown (Windows Ink (default) / WinTab). WinTab opens a WinTab 1.4
system context on PhotoCraft's window and polls pressure and the eraser end
(tilt on devices that report orientation axes; rotation only with a pen and
driver that report twist) into the stylus feed. The row says to turn Windows
Ink off in the tablet's software utility; the choice applies at next launch.

- crates/tablet: Windows-only wintab/wintab-sys backend. Devices with
  orientation axes use the orientation packet; pressure-only devices open a
  packet without it and report neutral tilt. Leaving is the driver's hardware
  proximity message (WT_PROXIMITY) and the packet's out-of-context status, with
  a long fallback for drivers that never report either. Overlap priority
  follows window focus, and the message hook requests a frame for each WinTab
  message so pressure-only strokes update without cursor movement.
- apps/photocraft: install the backend when the preference is on; poll it at
  the start of each frame; the installed wake repaints the UI.
- ui-egui: TabletPollFn service; the Windows-only Pen Tablet row with the
  Tablet input dropdown and the note.
- engine: tools.tabletInput (windowsInk/winTab), default windowsInk.
- docs: hardware-parity WinTab gap entry, qualifying tilt to orientation axes
  and rotation to twist-reporting pens.

Tested locally on a Wacom tablet with Windows Ink off: pressure, tilt and the
eraser end reach the brush (rotation where the pen reports twist); the default
path is unchanged.

* WinTab: a message that finds the state borrowed is skipped, not a panic in the hook

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* WinTab: rustfmt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Scorecard: count the Tablet input setting

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-06 18:39:40 +01:00
FredApps d2ce418bb3 Merge pull request #11641 from wanikhawar/claude/agitated-jones-8e1a8e
A little free memory no longer refuses every PSD; the refusal says what to do
2026-11-06 18:36:17 +01:00
FredApps 91a2fd1d85 Merge pull request #11652 from wanikhawar/claude/stoic-yalow-d695ab
A scratch folder that stops answering no longer freezes the app
2026-11-06 18:28:41 +01:00
FredApps ce97bde34b Merge pull request #11628 from wanikhawar/claude/brave-wu-261567
Network scratch folders report their own free space, or say they can't
2026-11-06 18:15:40 +01:00
FredApps d41e29a24f fix(ui): identify the active scratch directory in warnings 2026-11-06 17:51:33 +01:00
David Mann 7919429708 Merge remote-tracking branch 'origin/main' into feat/crop-task-bar-10890 2026-11-06 17:50:28 +01:00
David MannandClaude Opus 5.5 c7b5373ba8 Crop: Contextual Task Bar under the crop frame, as a reusable task-bar widget (#10890)
The Crop tool gets the reference application's contextual task bar: a small floating
bar centred 11 pt under the crop frame with a grip, the preset dropdown (the options
bar's own, so both stay in sync), Straighten, a ⋯ menu (Hide bar, Reset bar position,
Pin bar position) and, while a crop is pending, Cancel and Done. It follows the frame,
stays inside the canvas, and stays put once dragged or pinned. Window › Contextual Task
Bar (after Tools, as in the reference) shows and hides it.

The bar itself is a reusable widget (widgets/task_bar.rs): position rule, grip, ⋯ menu
and the hide/pin/place state in Panels (kept with the panel layout across restarts,
read by ui.inspect › taskBar, set by ui.set {panels}). A context supplies only its
controls and where ⋯ goes; the Crop contents are tools/crop_task_bar.rs. Generative
Expand stays out until #41.

Also: Lucide pin and rotate-ccw icons, six new strings in all 27 catalogues, parity
661/661 (FLOOR raised), control-protocol docs. Three tests about the options bar's
Ratio dropdown now hide the task bar, which shows the same dropdown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:50:20 +01:00
0b775dab11 Integration: keep the Korean rows, drop the session notes (#8185)
docs/korean-translation-validation.md records one agent session's checks
against a base from October (a "root task", a correction ZIP, other apps'
string tables); it says nothing a reader of docs/ can use. The 344 rows #8185
adds on top of main's ko.tsv stay (the merge kept main's wording for the 14
keys where both differ and dropped the 3368 rows main already has).

Co-authored-by: AKY <85772856+arksky1@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:33:07 +01:00
f236f0f6a4 Integration: Thai test compiles; Tamil catalog rows, plurals and attribution (#10241, #10359)
#10241: `th.0.plural(5)` calls a function-pointer field with method syntax
(E0599), so the ui-egui test target did not build; call it as `(th.0.plural)(5)`
(CodeRabbit). Add the ATTRIBUTION.md row for th.tsv and Thai to the licence
header (review ask).

#10359, from the review asks on the PR: two rows used spaces instead of a TAB
(Layer Mask Display Options..., Proportional Lining) and two had an empty
fourth column; "Scratch: {size}" translated the placeholder, so it rendered
literally; "Zoom In (hold, drag to scrub)" was split into a second "Zoom In"
key; "Print Settings..." lost its trailing ellipsis to a space. Tamil counts
take one|other, so the 28 two-form @plural rows now use plural_one_other; the
entry moves to the end of the registry. Adds the ATTRIBUTION.md, licence and
docs/localization.md rows, and tamil_tags_plurals_and_placeholders, which fails
on the old plural rule and placeholder.

Co-authored-by: Thanawatttt <89511939+Thanawatttt@users.noreply.github.com>
Co-authored-by: NewsBaba <346041388+newsbaba24x7@users.noreply.github.com>
Co-authored-by: Tanish Manku <13985398+tanish2k09@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:32:39 +01:00
David Mann b5acb4c622 Merge origin/main into integration-batch-19 2026-11-06 17:32:14 +01:00
FredApps 8d2ee0787f Merge scratch query updates into memory admission policy 2026-11-06 17:29:23 +01:00
FredApps aee46a2fc6 Merge remote-tracking branch 'origin/main' into fix/10164-final-prune-u2 2026-11-06 17:28:48 +01:00
FredApps 07580bfb34 Merge commit '898979da306fe9af29e2ec60341951f098225cb5' into review/g-11652-update 2026-11-06 17:28:13 +01:00
FredApps 898979da30 Merge main into scratch folder capacity queries 2026-11-06 17:27:38 +01:00
FredApps 8ab527b1e6 Merge pull request #11474 from wanikhawar/claude/selective-colours-isolation-329d87
Keep each colour's values in the Selective Color dialog
2026-11-06 17:26:42 +01:00
FredApps c8e4376ec6 Merge pull request #11513 from wanikhawar/claude/investigate-issue-e27e90
Windows: count scratch room when opening large files; refusal names the build's limit
2026-11-06 17:26:22 +01:00
David Mann 3768e84b67 Merge pull request #9480 from davidmann4/fix/remove-enable-animations
Interface: remove the Enable animations preference (#9479)
2026-11-06 17:25:38 +01:00
David Mann 16348db38b Merge pull request #9138 from davidmann4/fix/9137-control-click-coord-range
ui.click / ui.move reject coordinates beyond the screen range (#9137)
2026-11-06 17:24:27 +01:00
Khawar Zamman Wani 146d49f5a2 PSD write recipes: keep every exported candidate and pin the base file (#11607)
* PSD write recipes: keep every exported candidate and pin the base file

A case that failed after export dropped out of manifest.json, losing the
file a reference-editor check most needs. The CLI also reopened the corpus
path after the hash was taken.

- Keep the candidate and its hash once export succeeds.
- Run the CLI on a copy of the hashed bytes, so it never opens the corpus.
- Compare numbers by value, so 17 equals 17.0.
- tracking-split also checks runs 0 and 2 and all three run lengths.

Part of #6130.

* PSD write recipes: compare large integers exactly, reject case-only id clashes

Converting to f64 made 9007199254740993 equal 9007199254740992. Ids that
differ only by letter case name one output directory on a case-insensitive
filesystem, so they are now rejected as duplicates.

* PSD write recipes: test that the CLI receives the hashed bytes

* PSD write recipes: reject the contour library commands

Their path param can read or write any file, including the pinned base and
the corpus, and they edit no document.
2026-11-06 17:23:40 +01:00
David Mann 3fe08580ae Merge PR #8185: Add Korean support
# Conflicts:
#	crates/ui-egui/src/i18n/ko.tsv
2026-11-06 17:23:35 +01:00
David Mann cc5044d5b4 Merge PR #10241: i18n: add Thai UI catalog
# Conflicts:
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/i18n/LICENSE-translations.txt
2026-11-06 17:23:08 +01:00
David Mann c9e48117dd Merge PR #10555: i18n: add Azerbaijani UI language
# Conflicts:
#	crates/ui-egui/src/i18n/LICENSE-translations.txt
#	docs/localization.md
2026-11-06 17:23:00 +01:00
David Mann bcf818cca4 Merge PR #10547: i18n: add Romanian (ro) UI translation
# Conflicts:
#	ATTRIBUTION.md
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/i18n/LICENSE-translations.txt
#	docs/localization.md
2026-11-06 17:22:40 +01:00
David Mann 50d7ff9722 Merge PR #10361: i18n: add Urdu (ur) UI translation
# Conflicts:
#	ATTRIBUTION.md
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/i18n/LICENSE-translations.txt
#	crates/ui-egui/src/text/direction/tests.rs
#	docs/localization.md
2026-11-06 17:22:15 +01:00
David Mann 10608c2966 Merge PR #10365: i18n: add Hebrew (he) UI translation 2026-11-06 17:21:26 +01:00
David Mann 8df0c8ba54 Merge origin/main into fix/crop-overlay-and-fill-defaults
# Conflicts:
#	crates/ui-egui/src/tools/crop_ui.rs
2026-11-06 16:25:10 +01:00
Khawar Zamman Wani cd2250cb25 Scratch folder queries: address second review
A stuck close no longer holds up the files queued behind it (up to four
closer threads), and a query identifies the current file by the configured
folder. Tests don't read the room and the status across a late answer, and
the growth-check step proves its query is stalled.
2026-11-06 20:48:08 +05:30
David Mann eb83e5cc22 Merge PR #11092: Add Group filter to Layers panel (#10883) 2026-11-06 15:57:07 +01:00
David Mann eaddba69bd Merge PR #11249: Actions: load and save Blend If and Gradient Fill layers (#10771) 2026-11-06 15:36:23 +01:00
Khawar Zamman Wani e01c8719a0 Scratch folder queries: address review
The whole folder change now waits 2 s at most, old files close on one
background thread, the cap counts query threads until they finish, and
writes during a query aren't counted twice. Capacity is refused if a sweep
paused spilling meanwhile, a query opens a file unless this folder has one,
and on macOS an unrelated dead mount only costs the purgeable figure.
2026-11-06 19:44:03 +05:30
92de311b2b Actions: keep more Blend If and Gradient Fill forms exact (#11249)
Review fix-ups on #11249 after merging main:
- A midpoint outside 5..95 %, transparency stops out of range or out of
  order, and a Gradient Fill Set without transparency stops stay
  reference-application steps instead of playing clamped or keeping the
  layer's own transparency.
- An inverted Blend If range stays a reference-application step; the
  command rejects it at play.
- The Layer Style dialog's OK records `Lefx` = {Scl} beside Blend If on a
  layer without effects (measured). That Set is still the dialog's one
  step and saves back with the `Lefx` it was recorded with.

Co-Authored-By: NaufalDzz <90562913+NaufalDzz@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 15:07:32 +01:00
David Mann 72645904c7 Merge remote-tracking branch 'origin/main' into pr-11249
# Conflicts:
#	crates/engine/src/cmd/atn_cmds/steps_make.rs
#	crates/engine/src/cmd/atn_cmds/tests.rs
#	docs/atn.md
2026-11-06 14:55:00 +01:00
David Mann 22e03d0bcb Merge PR #9876: New Guide: add a position unit selector for pixels, millimeters and inches 2026-11-06 14:53:38 +01:00
2a9426cfe2 Merge origin/main into #11092 (Group filter) and fit it to main's filter row
Main added Effect, Attribute, Color, Smart Object and Artboard to the Layers
panel filter. Group is now the last type in the list, and works like Artboard:
`Filter::with_selection` fills the listed rows once per frame from
`group::listed`, so the panel, the deselect-on-apply step (#10879) and the
control channel all see the same rows; `shows_in`/`group_ids` and the
layers.rs change are gone. This also removes the duplicate `mod group;` and
`mod tests;` lines (E0428) and the rustfmt issues from the review.

- `group::listed` walks the tree with a stack instead of recursion and
  returns `LayerId`s.
- `Filter::show_all` is documented: Group keeps each group open or closed.
- Tests go through `Filter::of_app` and `panel_rows`, as the panel does,
  plus a deselect-on-apply case and a document without groups.
- control-protocol.md: `group` added to main's `layerFilter` entry.

Co-Authored-By: Nurana100 <Nurana100@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:42:50 +01:00
Taxperia 4019112d1d i18n: fix Turkic UI casing and remove unrelated parity edits 2026-11-06 16:09:08 +03:00
Khawar Zamman Wani 6c720c3765 Merge remote-tracking branch 'origin/main' into claude/stoic-yalow-d695ab 2026-11-06 18:38:44 +05:30
Khawar Zamman Wani 2c68c07dbf A scratch folder that stops answering no longer freezes the app
Opening and measuring the folder ran under the config lock, which the UI
takes every frame, and could run on the UI thread itself. They now run on
a short-lived thread, one per folder and question and 16 overall; callers
wait at most 2 s, and a late answer applies if the folder is still current.
No answer counts as unmeasured, or pauses spilling if nothing is open yet.
2026-11-06 17:45:34 +05:30
Khawar Zamman Wani 1ce1bced95 PSD admission: a little free memory no longer refuses every file
With 1 GiB or less of free RAM, or 512 MiB or less of commit headroom, the
hard limit was exactly 0, so even a small file was refused with a message that
didn't say memory was low.

The reserve now shrinks with the measurement: up to a quarter of free RAM opens
automatically, the rest goes to approval, and an approved import always leaves
at least 256 MiB free. Limits are unchanged for automatic opening above 4/3 GiB
free and for approval from 4 GiB free. A refusal set by measured memory now
gives the free amount and says to close other apps and try again, and the
approval prompt warns when little memory would be left.

An unreadable cgroup still measures Some(0) and stays refused.
2026-11-06 17:03:50 +05:30