crates/ui-egui/tests/it/main.rs: both mod lines kept. docs/whats-new.md, docs/parity-checklist.md: both sides' entries, header and LR-BEHAV-ACCESS row combined.
docs/parity-checklist.md, docs/ui-parity.md: headers, the KEYC-METADATA and LRC-LIB-KEYWORDS rows carry both sides' changes; revision rows kept from both.
photo.clearLabel takes no colour, but the toast code read params[label] for
it as for photo.label, so photo.clearLabel {label: red} cleared the photo and
showed 'Red Label'. The colour is read for photo.label only.
Setting a colour label is photo.label with the colour as a parameter, and the
keyboard shortcuts editor binds a key to a command, not to a parameter, so
only 6-9 had keys and clearing a label could not be given one. photo.clearLabel
is the same as photo.label with none, as a command of its own. The Photo >
Set Color Label > None row runs it and shows its key.
A data line such as `nan 0 0` starts with a letter and was skipped as an
unknown keyword, so a file with enough other entries still parsed.
(CodeRabbit review on #2540.)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous commit's sections.rs went through a PowerShell read and
write in the Windows ANSI code page, which turned …, – and ▸ into
mojibake in five album-menu labels (Create Album…, Sort Albums A–Z, …)
and two doc comments, so the labels missed their translation keys
(CodeRabbit on #3392). The file's text outside missing_count is now
byte for byte what it was before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A catalog change seen while a timed refresh of the Missing Photos count
is running cannot start its recount until the refresh ends, and the
refresh is not pending work, so settle() could return before either
finished and the row the recount adds moved the folder rows afterwards
(CodeRabbit on #3392).
The change is now counted as pending from the frame it is seen
(`owed`); the recount takes that entry over when it starts and drops it
once its count is stored. settling_waits_for_a_recount_owed_during_a_timed_refresh
adds a missing photo while a slow refresh runs and fails without this.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
While a headless run settles, its simulated clock runs several times
faster than wall time, so with every Missing Photos count pending, a
count that takes about a second started the next 5 s refresh before the
last one finished and settle() never ended (120 s timeout with a 1 s
count, 48 s with 600 ms). That would also stall lightcraft-cli snapshot
on a library on a slow share.
Only the first count and a recount after a catalog change, which add or
take away the Missing Photos row, are pending work now; the timed
refresh is not. Settling takes as long as the count (1.0 s for 1 s,
3.0 s for 3 s). The regression test also checks that settling ends
while a slow count refreshes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sidebar's Missing Photos row appears when the background count of
missing files lands, and moves every row below it down. That worker was
not counted in fs_cached_running, so Headless::settle() did not wait for
it: on a busy machine the row appeared after settling, and a click aimed
at a folder row from the settled layout landed on the row above it
(a_folder_menu_locates_its_missing_tree_only located `other` instead of
`trip`).
- missing_count adds itself to the fs_cached_running counter before it
starts and takes itself off after the count is stored, as fs_cached does
- the worker starts with thread::Builder::spawn instead of thread::spawn,
which panics when the OS refuses a thread; on failure the last count
stays and the next refresh tries again
- settling_waits_for_the_missing_photos_count delays the worker by 1 s
(test-only field on LightcraftApp, which ui.set does not rebuild) and
fails without the fix
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UPDATE_APP (native builds; craft-update is a native-only dependency) carries our 128 px icon and accent (#f2a516, its colour in ArtCraft Launcher). The updater, the self-update
helper and craft-update's startup prompt all get them through crate::UPDATE_APP; the
prompt draws the icon, the accent and "by ArtCraft" (craft-update's default developer).
craft-update is pinned to storytold/craft-libs main at 1065653e7 (#434).
Clippy fixes for Rust 1.99 in untouched code (same logic):
- crates/engine/src/cmd/export.rs
- crates/ui-egui/src/dialogs/rules_editor/rules_move.rs
- crates/ui-egui/src/panels/detail.rs
Cmd+Alt+K / Ctrl+Alt+K ends the full-screen preview before it opens the
Keywords panel or starts painting. With an empty keyword box it also turns
off an active targeted-adjustment tool and ends the current edit
interaction, as opening a panel from the menu does.
Follows main's split of menus.rs into menus/ and of the keyword tests into
keywords/tests.rs: Set Keyword Shortcut moves to menus/ui_commands.rs and
menus/run.rs, its catalog test to keywords/tests.rs, and the docs name the
moved test files.
The existing synthetic lossy RGB fixture tiles are re-declared grey by a
header edit (colour space RGB to Grey, dropping the 6-bit primaries field
a grey encoding does not carry, per the ColourEncoding bundle). Their XYB
frame data is unchanged, so they decode as one grey plane whose rendered
channels differ. The test checks decode against the gradient's BT.2100
luminance in the linear and sRGB curves.
Refs #275
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ti8KemZbjE2ZgHgV1q1BM
Lightroom Classic's HDR and panorama merges of monochrome raws store a
one-plane LinearRaw image as lossy (XYB) JPEG XL tiles whose codestream
declares a grey colour encoding (16-bit float with a linear curve, or
16-bit integer with the sRGB curve). Those were refused as "lossy JPEG XL
tile with a single colour plane", so the files opened preview-only.
A lossy grey tile is still coded as three XYB channels. It is now
restored like the RGB case: jxl-oxide renders linear sRGB (never the
declared encoding, which would clip), the single plane is the luminance
(CIE Y, D65) of that, then the declared transfer curve is applied.
One plane must be declared grey and three RGB; HDR curves, other white
points and intensity targets above 255 stay unsupported.
RENDER_CACHE_VERSION 70 -> 71: files that showed their embedded preview
before render from raw data now, under the same content key.
Refs #275
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ti8KemZbjE2ZgHgV1q1BM
A keyword picked in one library stayed picked after another library opened, so Cmd+Shift+K edited a keyword with the same path in the new library without a new pick.