Commit Graph
4062 Commits
Author SHA1 Message Date
aiongg 63ab092576 View: F8 on a right panel that isn't showing brings it forward in its mode
When the right panel is open but minimized or behind another tab, F8 keeps
its mode instead of switching to the one it last hid, and view.rightPanel
reveals Tools. Test: F8 on a minimized floating Tools window in Crop opens
the window and stays in Crop.
2026-10-24 23:37:41 +00:00
aiongg e442e3d220 Docking: a panel with no recorded place opens beside the photo on its side
Showing a panel that has no hidden entry skips craft-ui's right-edge
fallback and opens it beside the photo view on the panel's default side.
Test: Library opens to the left of the photo, Presets to the right.
2026-10-24 23:36:03 +00:00
aiongg ee1576682a Docking: a drop at the window's edge makes no dock column
The side panels are frames whose widths LightCraft tracks, so new_dock_zones
is off. Test: an edge drop of Tools leaves the layout without a Node::Dock.
2026-10-24 23:33:27 +00:00
dotCooCoo 1b0a9dae1b LR-META-INFO: the Info panel's GPS field is a TextField, so Esc gives an edit up
The GPS box was an egui TextEdit: Esc left the field with the typed text
kept, and leaving the field saved it. It is now the app's TextField, as the
other Info fields are: Esc puts the text back and saves nothing, and the
field gets the Cut / Copy / Paste / Select All menu.
2026-10-24 15:49:45 -07:00
aiongg b2f6246314 Docking: repin craft-libs 6e7f285 (the docking follow-ups) 2026-10-24 22:29:00 +00:00
aiongg a27d8c05d4 Docs: ui.dock above and below name the target's group 2026-10-24 22:19:29 +00:00
dotCooCoo 7a4e842dd5 LR-META-INFO: an Info field saves to the photos selected when its edit started
The text fields and GPS saved with no `ids`, so `photo.setMeta` wrote to
whatever was selected when the edit ended. A selection change during an
edit then gave the typed text to the new selection. Each edit now keeps
the selected photos from its start and saves to them.
2026-10-24 14:51:15 -07:00
aiongg 5b7a4e9a94 Docs: ui.dock move lists the tab, above and below zones 2026-10-24 21:31:46 +00:00
aiongg a70d7638a0 Docking: repin craft-libs 1774443; a dragged divider keeps its panel's width without app code
craft-ui and craft-docpath are pinned to craft-libs
17744430be327d0257496a6a31c8d38fe20a6756, where a divider drag keeps the
split's sizing mode. LightCraft no longer turns dragged ratios back into
side-panel widths.
2026-10-24 20:45:00 +00:00
dotCooCoo b572dee19f KEYC-METADATA: Alt+0 / Alt+Shift+0 go to the next / previous keyword set
Lightroom Classic's keyboard shortcut page lists Option+0 / Option+Shift+0
(Alt+0 / Alt+Shift+0 on Windows) for cycling forward and backward through
the keyword sets; LightCraft had no key or command for it. Next Keyword
Set (keyword.nextSet, Alt+0) and Previous Keyword Set
(keyword.previousSet, Alt+Shift+0) make the set after or before the
current one current, in the Keyword Set menu's order: Recent Keywords,
then the saved sets. The keys wrap around at either end, and Alt+1 to
Alt+9 then apply the new set's keywords.

The two command labels have rows in every catalog. The KEYC-METADATA and
LRC-LIB-KEYWORDS rows, docs/ui-parity.md and docs/library-shortcuts.md
list the keys.
2026-10-24 12:55:46 -07:00
aiongg c964b7f654 Docking: a dragged divider beside Library or Tools keeps that panel's width
craft-ui stores a moved divider as a ratio. After each frame the split
beside a side panel takes the width the panel was drawn at, so the panel
keeps its width when the window resizes and left_width / right_width follow
the drag.
2026-10-24 19:44:32 +00:00
aiongg 5ce171da23 Docking: the workspace, its commands and their parser come from craft-ui (craft-libs 16fb3d4)
craft-ui and craft-docpath are pinned to craft-libs 16fb3d46e1eaa0d455465e4e66a3ac7b17b55bd3.
The saved workspace is craft_ui::docking::Workspace<Panel>; settings written
before it had a version load as version 1. ui.dock params parse as the shared
DockCommand and apply through Workspace::apply_all. LightCraft keeps its
panels, permissions, default layout, photo-view checks, the fallback beside
the photo view for a panel with no recorded place, and its settings file.

The photo view takes side splits (accepts_splits on PROTECTED), so panels
still open and move beside it.

Tests: a version 1 workspace file loads and reopens its hidden panel; a drag
of a group by its bar moves both of its panels.
2026-10-24 19:23:08 +00:00
dotCooCoo 8d67b834e4 LR-PREF-SHORTCUTS: a declared shortcut yields to a key the saved keymap gives another command
When a saved keymap gave a key to one command and a later build declared
the same key as another command's default, one press ran both commands,
and menus and Help > Keyboard Shortcuts listed the key on both.

binding() now drops a declared shortcut while the keymap gives its key to
another known command, other than its contextual partner. handle(),
conflicts(), shortcut_of(), the menus and the shortcut editor read it.
In the editor such a row counts as changed, so its restore button takes
the key back.

handle() also let every saved entry stop the fixed keys on its key
(Enter in the grid, secondary keys such as Shift+X, the rating and
label digits, Home, End and Shift+arrows), including entries for
commands the build does not know. It now reads only the entries of
known commands, as binding() does, so a stale entry in ui.json no
longer silences Shift+X, a rating digit or a label digit.
2026-10-24 11:20:04 -07:00
dotCooCoo e25cc3ca0b LR-META-INFO: Selected Photos reads the selection when the active photo is outside it
The active photo can be one that is not selected (library.select with an
`active` outside `ids`). With Selected Photos on, the Info fields then
showed that photo's values and marked fields Mixed against it. The fields
now show the active photo's values only when it is selected, and else the
first selected photo's, and compare the selected photos with those.
2026-10-24 10:43:44 -07:00
dotCooCoo 2d5ce5382b Merge branch 'main' into feat/loupe-info-briefly 2026-10-24 10:32:28 -07:00
dotCooCoo cc557e189d KEYC-METADATA: Cmd+Alt+Shift+C / V copy and paste metadata
Copy Metadata and Paste Metadata had no shortcut. They now use
Cmd+Option+Shift+C and Cmd+Option+Shift+V on macOS and
Ctrl+Alt+Shift+C and Ctrl+Alt+Shift+V on Windows and Linux, the keys
Lightroom Classic's keyboard shortcut page lists for copying and
pasting metadata in the Library module. Both keys also work when
Windows and Linux deliver them as clipboard events. The KEYC-METADATA
row now lists the keys LightCraft binds (Cmd+S, the two new keys and
Alt+1 to Alt+9 for keyword sets) and every other key of that table
that is still missing. Gap 28 in docs/gaps.md and the Library keys in
docs/ui-parity.md list the two new keys.
2026-10-24 09:13:54 -07:00
dotCooCoo a9d2c594b0 LRC-PRINT-TEMPLATES: print template tests clean up their folder on failure
The template file tests now create their folder through a Scratch guard
that removes it when the test ends, including when an assertion fails,
as tests_folders.rs and tests_slideshow_export.rs do.
2026-10-24 08:56:00 -07:00
dotCooCoo 9fcf7f5b88 LRC-DEV-VIEWOPTIONS: switching libraries restarts Show Briefly When Photo Changes
Photo IDs are local to a library, so the loupe's last photo is forgotten when another library opens, and a photo there with the same ID shows the info overlay again.
2026-10-24 08:24:49 -07:00
dotCooCoo d2c8d46a7b Tests: the launch-list read-only test compares a held lock file without reading it
On Windows, tests_launch_library::listing_the_libraries_leaves_every_folder_byte_identical
failed every time with os error 33. Its snapshot read every file in the folder, including the
lock file of the library the test holds with LibraryLock::acquire. On Windows that lock is
LockFileEx, and reading the locked bytes through another handle fails with
ERROR_LOCK_VIOLATION.

The snapshot now records each file's length as well as its contents and modification time.
When the read of a catalog.lock fails with os error 33 on Windows, its contents are left out
and the file is compared by its length and modification time. Every other file is still
compared byte for byte, and on other platforms the held lock file is too. The app does not
read a held lock file anywhere, so only the test changes.
2026-10-24 08:03:17 -07:00
Brandon Thomas 38f8d25087 Merge PR: integration batch 44 (11 community PRs)
Integration batch 44: 11 community PRs
2026-10-24 11:00:48 -04:00
Brandon Thomas 5f8593a074 Merge PR #673 2026-10-24 10:20:14 -04:00
Brandon Thomas f7d11bf750 Merge PR #1956 (with maintainer follow-up)
# Conflicts:
#	docs/whats-new.md
2026-10-24 10:20:14 -04:00
Brandon Thomas 82c39a9847 Merge PR #2011 (with maintainer follow-up)
# Conflicts:
#	docs/whats-new.md
2026-10-24 10:20:14 -04:00
Brandon Thomas d7e7639d7a Merge PR #2800 2026-10-24 10:20:13 -04:00
Brandon Thomas 3f1e5c21d6 Merge PR #2775
# Conflicts:
#	docs/gaps.md
#	docs/parity-checklist.md
2026-10-24 10:20:13 -04:00
Brandon Thomas bb82525413 Merge PR #2755 2026-10-24 10:20:13 -04:00
Brandon Thomas 7ed3f0f046 Merge PR #1122
# Conflicts:
#	crates/catalog/src/tests_local.rs
2026-10-24 10:20:13 -04:00
Brandon Thomas 749928088a Merge PR #2699 2026-10-24 10:20:13 -04:00
Brandon Thomas 621c4dcb6e Merge PR #2761 2026-10-24 10:20:13 -04:00
Brandon Thomas 57c639246b Merge PR #2762
# Conflicts:
#	docs/parity-checklist.md
2026-10-24 10:20:13 -04:00
Brandon Thomas 747caeeb58 Merge PR #2788 2026-10-24 10:20:12 -04:00
Brandon ThomasandClaude Opus 5.5 c19e1bd095 Tone Curve: What's New and parity row for the draggable parametric graph; the hover test compares with a frame away from the line
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:19:51 -04:00
Brandon ThomasandClaude Opus 5.5 0deec1251f Merge main into #673
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:14:13 -04:00
Brandon ThomasandClaude Opus 5.5 a1ee846ad6 Merge main into #2011
Resolves the parity summary (regenerated), drops a duplicated #[cfg(test)], files the What's New entry
under today's date and bumps the checklist's Last updated line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:13:16 -04:00
Brandon ThomasandClaude Opus 5.5 5ba9b48d30 Merge main into #2800
main replaced "Show Clipping" with "Clipping": the PR's Beschneidung term moves to the new key.
Also takes CodeRabbit's two wording suggestions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:08:20 -04:00
dotCooCoo 0b1b47ee7b LR-META-INFO: the Info panel can show metadata for the selected photos
With several photos selected, the Info panel offers Show Metadata For:
Target Photo (the default) shows the active photo's values as before,
and Selected Photos shows the values the selected photos share. A text
field or GPS where they differ is empty with a Mixed hint, and
Copyright Status shows Mixed. What is typed there is saved to every selected
photo, and a Mixed field typed in and left empty clears it on all of
them. A field left as it was saves nothing, even when the choice
changes during the edit. The choice is saved with the app settings, and
`view.infoSelectedPhotos {on?}` sets it for an agent.
2026-10-24 07:03:31 -07:00
Brandon Thomas 50874ad2f6 Merge main into #2755
# Conflicts:
#	crates/engine/src/cmd/library.rs
2026-10-24 10:00:50 -04:00
aiongg c414ef06ec Merge pull request #2689 from francoisgn/round3a-integration
Round 3a integration: 42 PRs of #2580, built and tested locally
2026-10-24 09:39:25 -04:00
Julian ZahnowandClaude Opus 5.5 18b84f97d1 i18n(de): review the interface strings and formats messages
A pass over all 2,565 interface strings and 299 formats messages of the
German catalogs (What's New lines not included). 108 messages change:

- Lightroom terms: Tönung (Tint), Beschneidung (Clipping)
- one word per thing: Bedienfeld (panel; Bereich stays for sidebar
  sections), Begleitdatei (sidecar), Dia (slide), Zuschnitt (crop),
  Farbmarkierung (label) where "Markierung" read as the pick/reject flag,
  Verschlusszeit, Smart-Album, Perspektivkorrektur (Upright),
  Aktivitätsstapel
- "Ihre Dateien/Fotos" at the start of a sentence read as the formal
  "your" in a du catalog; rephrased
- double colons and "1 Fotos" in count messages, awkward phrasings
- spaced en dash instead of em dash, no space before a final ellipsis,
  German quotes around {profile}

The terms are listed in docs/localization-de.md; localization-parity
records the review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 15:28:43 +02:00
Marco Arnulfo b0389651c9 LR-FILT-LABEL: the filter_label test builds the expected chip text from the catalog's values, and the Finnish pick/reject strings no longer have a coverage test (#2729) 2026-10-24 15:04:41 +02:00
Marco Arnulfo 1c6b22673a Add the pick and reject flag names to the Finnish catalog 2026-10-24 14:51:44 +02:00
Marco Arnulfo ab28690d06 LR-FILT-LABEL: group the plural labels in the chip when label and labels exclude each other 2026-10-24 14:51:44 +02:00
Marco Arnulfo afbd931561 LR-FILT-LABEL: the label chip and filter bar show what label and labels let through together, not their union 2026-10-24 14:51:44 +02:00
dotCooCoo a4ddb9198f LRC-DEV-VIEWOPTIONS: View Options can turn off the loupe's "Rendering…" message
View Options gets the Loupe View tab's General section with "Show message
when loading or rendering photos". It is on by default, so the loupe keeps
saying "Rendering…" as before. With it off, the loupe does not show the
"Rendering…" pill while an edit renders, or the "Rendering…" text over an
empty loupe; the "can't be opened" messages still show. The choice is saved
with the app settings, and `view.viewOptions {loupeMessages}` sets it for
an agent.
2026-10-24 04:45:18 -07:00
dotCooCoo 758c5e170a LRC-DEV-VIEWOPTIONS: the info overlay can show briefly when the photo changes
View Options had no Show Briefly When Photo Changes. A tick box under
Loupe Info 1 and one under Loupe Info 2 now choose the Info that shows
for 3 seconds each time the loupe changes to another photo while the
info overlay is off. Ticking one unticks the other. An overlay that is
on stays on and shows its own Info. view.viewOptions takes
briefly (off, basic or exposure), and the choice is saved with the app
settings; a settings file without it reads as off.
2026-10-24 03:23:50 -07:00
NetterSilverandClaude Haiku 5.5 098a1a2e72 Forget Local records directly in drive and share roots
Found while testing crates/catalog/src/local.rs:62 (folder_of), used by forget_local_plan at :192 and :204

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 09:51:09 +00:00
dotCooCoo 1c60abb586 LRC-PRINT-TEMPLATES: template changes that can't be saved are undone
print.template.save, delete and import changed the template list before
saving the preferences, and left the change in place when the save failed.
A retried import then saw its own unsaved copy and stored another one as
"Name (2)". The list now goes back to what it was when the save fails, as
library.holdView and the slide templates do.
2026-10-24 02:42:21 -07:00
dotCooCoo adf94a87cb LRC-SS-PLAYBACK: a manual slideshow waits for the arrow keys
The slideshow always advanced on its own after the slide duration.
The new Manual slideshow setting (Settings > Slideshow > Playback, or
manual in slideshow.playback and view.slideshow) keeps each slide, the
intro and the ending up until the right or left arrow or the control
bar changes it. Space, Esc, random order and repeat work as before.
Exports still use the slide duration. The setting is saved with the
library and in slideshow templates; a template without it reads as off.
2026-10-24 01:46:49 -07:00
Dylan M. TaylorandClaude Opus 5.5 23f54803e6 fix(tools): keep install-sam3.sh POSIX sh (no arrays for curl auth options) (#2760)
The script runs under #!/bin/sh; on dash the array assignment was a
syntax error. Pass the auth option and its value as two plain words.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 04:43:15 -04:00
e83bf7742e security: bound codec allocation to what a hostile file declares (#2769)
* security: bound codec allocation to what a hostile file declares

A GIF's first image descriptor could name a frame up to four times the
canvas budget and be charged that allocation before any size check saw
it; PNG's compressed text chunks were expanded through an unbounded
inflate; JPEG handed hostile frame headers to the allocating decoders
(zune for the common cases, jpeg-decoder for CMYK/scaled/lossless) and
let an APP1 flood drive quadratic metadata reassembly. Each now refuses
on the same max_pixels budget the other decoders honour, with a
regression test per gate.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Fix clippy collapsible_if in DCT-scale size check

* Check jpeg-decoder header on scaled path; cap APP1 markers in decode_codes8

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

---------

Co-authored-by: Codebuff <noreply@codebuff.com>
Co-authored-by: Dylan Taylor <dylan@craftmaker.dev>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:32:58 -04:00