Commit Graph
1516 Commits
Author SHA1 Message Date
Andrey VyrodovandClaude Opus 5.5 56dfc8d027 Issue #345: Synchronize Folder and the contact sheet in the activity stack
Synchronize Folder (#604) shows its scan ("Looking for changes", while
its dialog is open) and its run ("Synchronizing folder") as rows: the
scan's cross stops it and closes the dialog, the run's stops it like
Cancel did (what was done stays, as one undo step; the end says Stopped).
Its progress window is gone. The contact-sheet PDF export (#563), which
went through the export task already, gets a test for its row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 09:17:45 +02:00
Andrey VyrodovandClaude Opus 5.5 8c3c586b80 Issue #345: review fixes for the activity stack
A cross clicked in the frame its task ended no longer puts "no task N"
in the status bar: the row's cancel goes to the engine directly instead
of through the app's command runner, which reports every error there.

The face-scan row test scans demo photos no other scan test uses, so it
no longer joins the scan deadlock of #630 (with one of the existing pump
tests it hung 13 of 20 runs; now 0 of 20).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:50:56 +02:00
Andrey VyrodovandClaude Opus 5.5 e974a87cfb Issue #345: docs and parity for the activity stack
LR-BEHAV-BG-TASKS now cites activity.list / activity.cancel and lists
every job on the stack; the import and Build Previews rows no longer
describe progress windows and toasts; a what's-new entry.

Fixes the stack not growing when tasks arrive while it already shows a
row (an egui area lays out in last frame's size, and the scroll area took
that as all the room, so later rows were cut off), and adds the Russian
"Quit Anyway".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:50:54 +02:00
Andrey VyrodovandClaude Opus 5.5 1c89caa4a1 Issue #345: Find Missing Photos in the activity stack
Find Missing Photos shows a row (a sweep: the amount of work isn't known,
no cross) while it searches; the auto-import folder listing, which runs
every few seconds, stays quiet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:50:24 +02:00
Andrey VyrodovandClaude Opus 5.5 753ca97a4d Issue #345: AI Denoise in the activity stack
While a photo's AI Denoise picture is being made or waits its turn, the
stack shows "AI Denoise" with the running photo's tiles as a percentage
and its file name (no cross: what is made follows the Denoise amounts and
Settings). The row goes when the queue is idle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:50:20 +02:00
Andrey VyrodovandClaude Opus 5.5 3f3c204987 Issue #345: face scan in the activity stack
While photos are left to search for faces the stack shows "Finding
faces" with how many are done (no cross: the scan is switched off in
Settings). The engine keeps the scan's peak, so Settings and the stack
agree. Also translates the "Downloading model" label.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:50:17 +02:00
Andrey VyrodovandClaude Opus 5.5 de247ad54f Issue #345: model downloads in the activity stack
Downloading the SAM 3, face and AI Denoise models shows a row with the
model's name and the megabytes so far; its cross stops the download like
the Settings button. The denoise download tests get their own scratch
folders (they shared the face tests' names and could delete each
other's files).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:50:14 +02:00
Andrey VyrodovandClaude Opus 5.5 e9e8b5a933 Issue #345: photo merge in the activity stack
The final HDR / panorama merge shows a row with its percentage and stage
instead of the progress toast, and stops from its cross ("HDR merge
cancelled"). The activity tests now let the first renders finish before
they run, and the half-second check tolerates a slow frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:50:04 +02:00
Andrey VyrodovandClaude Opus 5.5 c3bb8e9916 Issue #345: Lightroom catalog import in the activity stack
Inspecting and importing a Lightroom catalog show a row instead of the
progress window; reading the catalog stops from its cross, adding the
photos and saving the index run to the end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:49:52 +02:00
Andrey VyrodovandClaude Opus 5.5 9c8a721389 Issue #345: preview builds in the activity stack
Build Previews, Build Smart Previews and Discard Smart Previews show a row
with the photo count and stop from its cross; the start toast goes, the
finish toast stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:49:38 +02:00
Andrey VyrodovandClaude Opus 5.5 1af0dd4fe3 Issue #345: folder scan in the activity stack
The import review's folder scan (and reading a folder for Local) is a
row in the activity stack: "Looking for photos…" while the folders are
listed, then the files read of the total. Its cross drops the scan at
once, without waiting for the file being read, as the old Cancel did.
The separate Scanning window is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:49:34 +02:00
Andrey VyrodovandClaude Opus 5.5 63d9b70356 Issue #345: activity stack polish
The cross sits at the right edge of its row (the name's area kept only
the text's width, so the cross followed short names). Seen in the
running app; a test pins it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:49:18 +02:00
Andrey VyrodovandClaude Opus 5.5 10e097abf6 Issue #345: import progress in the activity stack
An import (and Auto Import, and reading a folder for Local) registers in
the activity stack with the files done of the total; its cross and
activity.cancel set the import's cancel flag, so nothing new starts and
the result still reads "Import cancelled · N added" as one undo step.
The separate Importing window is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:49:15 +02:00
Andrey VyrodovandClaude Opus 5.5 dbf570c711 Issue #345: export progress in the activity stack
A background export registers in the activity stack with the photos done
of the total and the file in progress; its cross and activity.cancel set
the export's own cancel flag. The separate export panel at the bottom
left is gone; the result toast is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:48:58 +02:00
Andrey VyrodovandClaude Opus 5.5 98f65ff0d7 Issue #345: ask before quitting while tasks run
Quitting while an import, an export or another task that can be
cancelled is running asks first: Quit Anyway cancels them (then any
unsaved changes still get their own question), Cancel keeps working.
Tasks without a cross (the face scan, AI Denoise) pick up again on the
next launch and don't ask.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:47:58 +02:00
Andrey VyrodovandClaude Opus 5.5 af9b1063ca Issue #345: activity stack in the top-left corner
Every task in the engine's activity registry floats as a row under the
top bar once it is half a second old: its name, a progress bar (a sweep
while the amount of work isn't known), the count and what it is working
on, and a cross for the ones that can be cancelled. Three rows, then
"+N more". ui.inspect reports the same list as activity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:47:15 +02:00
Andrey VyrodovandClaude Opus 5.5 4e323ad26f Issue #345: activity.list and activity.cancel commands
The registry is reachable as commands, so the UI, the control channel,
the CLI and MCP list and cancel background tasks the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:45:25 +02:00
Andrey VyrodovandClaude Opus 5.5 533a382619 Issue #345: engine task registry (activity)
A registry of the background tasks in flight on Session: a job holds a
TaskGuard while it runs (dropping it, also during a panic unwind, removes
the row), adopts its existing cancel flag, and reports done/total in a
unit the frontend words. Groundwork for one progress stack for imports,
exports, preview builds and the other long jobs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:44:28 +02:00
Brandon ThomasandClaude Opus 5.5 5436951299 Contributors: credit GPT-6 Luna and opencode
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:23:24 -04:00
Brandon Thomas c545cc5e84 Merge pull request #659 from storytold/claude/integrate-batch-24
Integrate #607 follow-up, #655, #656
2026-10-10 02:18:46 -04:00
Brandon Thomas 4045eaed96 Merge PR #656
# Conflicts:
#	crates/gpu/src/lib.rs
#	docs/parity.md
2026-10-10 02:02:20 -04:00
Brandon Thomas b31e0e2ec6 Merge PR #655 2026-10-10 02:02:20 -04:00
Brandon Thomas 17af5ba949 Merge PR #607 (its follow-up commit; content applied above) 2026-10-10 02:02:03 -04:00
Alex ChambersandClaude Opus 5.5 aa6dfe3b30 LR-EDIT-LIGHT-HIGHLIGHTS: pale partly clipped skies turn white, not teal (#523)
Testing the first version on ILCE-7RM4 photos found a partly clipped sky between
bare branches leaning cyan to teal under #523's edit, where Lightroom shows white.
Where only green clipped, red and blue say such a sky is a pale cyan-blue; the
rebuild kept that colour until halfway to full clipping, and darkening and a camera
profile showed it. Colour borrowed from another surface (bright foliage below the
sky) could also push green up, with a small step where green first clips.

- highlight::reconstruct_with: the colour of a pale partly clipped pixel
  (saturation relative to the colour model's white below 0.2, easing off by 0.4)
  fades to the clipped neutral from the first clip on instead of from halfway;
  brightness and strongly coloured pixels keep the old schedule.
- Borrowed colour counts less and less as both the pixel's own channels and the
  rim's colour contradict it (0.15 to 0.4 stop); either alone can be wrong.
- Right past the rim every estimate continues the rim's colour (it used to hold
  the clipped channels at their clip, for the neutral estimate only), so the first
  clip has no step whatever lent the estimate. The rim is built whenever there is
  clipping.
- Nothing jumps where a later channel clips: in the rim distance and the
  contradiction, a clipped channel counts as the lower bound it is, and a channel
  goes over to that from 0.75 of its clip; a channel about to clip is a floor
  capped like the clip floor it becomes.
- Tests: a pale sky above yellow-green foliage with thin dark branches in it (no
  step where green clips, no green from the foliage, the same beside the branches,
  neutral well past the clip); the fringe test compares the sky beside the branch
  with the sky away from it, on its way to neutral; a band whose red clips second
  next to a rim of another colour renders without a step, in six layouts.
- docs/parity.md: the Highlights note. Render cache version 28.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:02:00 -04:00
Brandon Thomas 9e59e3dcea Merge pull request #657 from storytold/claude/integrate-batch-23
Integrate 59 community PRs (batches 21–23)
2026-10-10 02:00:34 -04:00
Brandon ThomasandClaude Opus 5.5 77421aeeda Web: no display-profile picker in the browser (#612 added the service)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:56:02 -04:00
hxwandClaude Opus 5.5 5a537d5d39 LR-BEHAV-GPU: no render is inside the GPU driver when the app quits (issue #620)
A render still running on a worker thread while the process exits crashes in the
driver (SIGSEGV in the NVIDIA Vulkan driver on Linux), where neither the panic
hook nor catch_unwind helps: pool workers were detached, the devices are statics
that are never dropped, and nothing on the way out waited for GPU work.

- gpu: every entry into a device (render, device creation, pool trim, denoise
  runner and tiles) is counted as work in flight (exit.rs). begin_shutdown()
  lets nothing new in; wait_idle(timeout) waits for what is inside.
- preview: JobPool keeps its workers. shutdown(timeout) and Drop discard the
  queued jobs and wait, bounded, for the running ones (2 s on drop); never for
  the calling thread, and not twice.
- engine: a render job caught by the shutdown gives up instead of rendering on
  the CPU, so quitting doesn't wait for it.
- app: on_exit ends with LightcraftApp::shutdown (2 s for everything), after
  settings and library are saved; the macOS menu-bar Quit goes through on_exit.

Not changed: the export, merge, denoise and import threads are still detached;
their GPU work goes through the gate, their CPU work is cut off at exit as before.

Tests: pool drop waits / is bounded / survives a panicked job and its own job
dropping it; the gate; GPU renders refused and the device not created after
begin_shutdown; the app's shutdown leaves no render worker. The crash itself
needs Linux + NVIDIA and was not reproduced here (Windows, DX12): 9 of 9 quits
of the app mid-render exit with code 0 in under 0.8 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:46:24 -05:00
Alex ChambersandClaude Opus 5.5 41a61b74fc LR-EDIT-LIGHT-HIGHLIGHTS: pale partly clipped skies turn white, not teal (#523)
Testing the first version on ILCE-7RM4 photos found a partly clipped sky between
bare branches leaning cyan to teal under #523's edit, where Lightroom shows white.
Where only green clipped, red and blue say such a sky is a pale cyan-blue; the
rebuild kept that colour until halfway to full clipping, and darkening and a camera
profile showed it. Colour borrowed from another surface (bright foliage below the
sky) could also push green up, with a small step where green first clips.

- highlight::reconstruct_with: the colour of a pale partly clipped pixel
  (saturation relative to the colour model's white below 0.2, easing off by 0.4)
  fades to the clipped neutral from the first clip on instead of from halfway;
  brightness and strongly coloured pixels keep the old schedule.
- Borrowed colour counts less and less as both the pixel's own channels and the
  rim's colour contradict it (0.15 to 0.4 stop); either alone can be wrong.
- Right past the rim every estimate continues the rim's colour (it used to hold
  the clipped channels at their clip, for the neutral estimate only), so the first
  clip has no step whatever lent the estimate. The rim is built whenever there is
  clipping.
- Nothing jumps where a later channel clips: in the rim distance and the
  contradiction, a clipped channel counts as the lower bound it is, and a channel
  goes over to that from 0.75 of its clip; a channel about to clip is a floor
  capped like the clip floor it becomes.
- Tests: a pale sky above yellow-green foliage with thin dark branches in it (no
  step where green clips, no green from the foliage, the same beside the branches,
  neutral well past the clip); the fringe test compares the sky beside the branch
  with the sky away from it, on its way to neutral; a band whose red clips second
  next to a rim of another colour renders without a step, in six layouts.
- docs/parity.md: the Highlights note. Render cache version 28.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:40:18 +02:00
Brandon ThomasandClaude Opus 5.5 c118f960b1 LR-IMP-FORMATS: render cache version 36 (#609 decodes HEIC colour like libheif)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:26:31 -04:00
Brandon ThomasandClaude Opus 5.5 e46e7ab265 Merge PR #646 (HDR peak threaded through #533's base_tone; V1 at peak 1 unchanged)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:26:27 -04:00
Brandon ThomasandClaude Opus 5.5 23af0a9d1c LR-BEHAV-LOCALIZE: French and Ukrainian for this round's new strings (smart-album rules, keyword list and sets, Synchronize Folder, ratings, crop angle)
The two new catalogs landed alongside PRs that added ~127 strings; the per-language
tests require them in every catalog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:25:38 -04:00
hxwandClaude Opus 5.5 3cdf18ba6d LR-VIEW-ZOOM: zoom windows cover a canvas wider than 2048 px (issue #652)
The loupe read the GPU's texture limit from the frame's raw input
(`i.raw.max_texture_side`). A native host (egui-winit) reports it in the
first frame's input only, so from the second frame on the loupe fell back
to 2048: every window render of a zoomed view was cut to 2048 x 2048 px,
and on a canvas wider than that (HiDPI, 4K, a large window) the strips
beside it showed the magnified whole-frame render. The whole-frame render
and the second-window and compare renders were capped the same way.

Read the limit egui keeps (`InputState::max_texture_side`) instead.

The headless host reported the limit in every frame, which is why no test
saw this: it now reports it once (and again when it changes), as a window
does. Two regression tests: the limit outlives the frame it was reported
in, and at 1:1 on a 2600 px canvas the window covers the canvas.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:18:54 -05:00
Brandon ThomasandClaude Opus 5.5 88de143dd1 HDR: default HDR settings aren't serialized (hash64 and cached previews unchanged); NaN-safe peak; checked AVIF size
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:15:51 -04:00
Brandon Thomas 259ddcc1a8 Merge PR #580 (its updated head; content already applied above) 2026-10-10 01:15:02 -04:00
Brandon ThomasandClaude Opus 5.5 3539de95ca Merge PR #628 (Auto renders under the photo's process, as #533 does)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:14:47 -04:00
Brandon Thomas 57f29bf8e1 Merge PR #636 2026-10-10 01:14:26 -04:00
Brandon Thomas d267a7acd5 Merge PR #640
# Conflicts:
#	crates/engine/src/media.rs
#	docs/parity.md
2026-10-10 01:14:26 -04:00
Brandon Thomas 37e95dd2fa Merge PR #651
# Conflicts:
#	crates/engine/src/media.rs
#	crates/raw/src/lib.rs
#	crates/raw/src/vendor/orf.rs
#	docs/parity.md
2026-10-10 01:14:25 -04:00
Brandon Thomas f35663590f Merge PR #633
# Conflicts:
#	crates/engine/src/media.rs
#	crates/raw/src/vendor/nef.rs
#	docs/parity.md
2026-10-10 01:14:24 -04:00
Brandon Thomas 78550e5de9 Merge PR #609
# Conflicts:
#	crates/engine/src/tests_import.rs
#	docs/parity.md
2026-10-10 01:14:24 -04:00
Brandon ThomasandClaude Opus 5.5 e7da679cb3 LR-IMP-FORMATS: word16_order reads sample pairs with as_chunks instead of indexing
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:10:36 -04:00
Brandon ThomasandClaude Opus 5.5 0982cae7d5 OmaStore: exec paths match the tarball layout (bin/, no usr/)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:08:30 -04:00
Brandon ThomasandClaude Opus 5.5 82566817e6 LR-IMP-FORMATS: drop references to analysis files that aren't in the repo
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:08:10 -04:00
Brandon Thomas 4bf125d116 Merge PR #623 (updated head) 2026-10-10 01:02:10 -04:00
Brandon Thomas b6f6a979e5 Merge PR #608 (updated head) 2026-10-10 01:02:10 -04:00
Brandon ThomasandClaude Opus 5.5 4a3f9e9b6d Apply #580's updated head (drops the DSC-R1 SR2 refusal)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:02:09 -04:00
Brandon Thomas 2ecb495d18 Merge remote-tracking branch 'origin/main' into claude/integrate-batch-22 2026-10-10 01:01:03 -04:00
SawizzleandClaude Opus 5.5 4e39a51b24 docs: drop the third-party link; the Windows path is the default install folder
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:50:51 -07:00
akvaithiandClaude Opus 5.5 7828f93c32 LR-HDR-EXPORT: HDR AVIF (10-bit Rec. 2020 PQ)
`encode_avif_pq`: linear Rec. 2020 with SDR white at 1.0 → PQ (SDR white at
203 cd/m², BT.2408), BT.2020 NCL YCbCr 4:4:4, 10-bit, with CICP nclx
(9/16/9, full range) and a clli box. ravif fixes the sRGB curve, so this
drives the rav1e + avif-serialize it already uses (no new crates).

Export: AVIF with `hdr` renders the HDR edit in Rec. 2020 and writes PQ.
Photos without an HDR edit export as before, in every format. CoreImage
decodes the file as HDR (same 3.1 % of the frame above SDR white as the gain
map JPEG of the same edit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:40:37 -05:00
akvaithiandClaude Opus 5.5 af06f2dbc1 LR-HDR-VISUALIZE: HDR controls in the Light panel, Visualize HDR, export option
- Light panel: HDR switch, headroom limit and an SDR Rendition flyout
  (shown with HDR on); Visualize HDR beside the switch.
- `Overlay::HdrRange` / `view.visualizeHdr`: the SDR render dimmed to grey,
  with pixels the HDR rendition puts above SDR white painted in four bands by
  stops above it. Rendered on the CPU from the float HDR render.
- Export dialog: "HDR output" for JPEG (gain map) and 32-bit TIFF.
- Parity (Q. HDR 2 ✅ 3 🟡, LR-EDIT-HDR-MODE ✅, LR-EXP-HDR 🟡), README, ROADMAP.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:40:37 -05:00