General was 970 pt wide and the other tabs about 600, because a row of
controls never wrapped and the widest row set the window's width; the
window was also as tall as each tab's content, so it moved up and down
between tabs and the tabs moved under the pointer. In a 900 pt wide app
window the row labels and the Close button of General were off screen at
the left, and a long library path made the window wider than the screen.
- settings::window draws the tab bar, which stays put, above the page of the
open tab, which scrolls: 560 pt wide and up to 640 pt tall whatever the
page holds, less when the app window is smaller. Each page keeps a scroll
position of its own, and one that goes on below shows its scroll handle
without the pointer on it. It is still drawn in the scroll area every
dialog has, which has nothing to scroll; in a window with under 120 pt for
the page (far below the desktop minimum) that area scrolls tabs and page
together, as before.
- A row's controls wrap in the room beside the label, further lines starting
under the first control, and a label longer than its column wraps in it
(Forget unchanged photos pushed its choices 8 pt out of line).
- Paths are one line, shortened from the front after either kind of
separator, with all of the path in a tooltip only when it was cut: Library
> Location, the folder Auto Import watches (it wrapped over several lines),
the smart previews folder (it lost its end, and had two tooltips) and a
monitor profile's file.
row(), choices() and TABS keep their signatures, the match on the tab is
where it was and the shared dialog code changes by one call, so the open
pull requests that add tabs and rows still merge. Below 640 pt of app
window a row holding a 240 pt field can still be wider than the page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On merge: the HDR histogram is applied in develop_reporting (#712 split develop), is skipped for
draft renders (a second render per drag tick), and HdrBins::bin clamps a hand-built split so it
can't underflow (test hdr_bins_with_any_split_stay_in_range).
#884 focuses a develop slider on click so the wheel and arrows adjust it, but a focused widget
owned the whole keyboard, so after touching a slider no shortcut fired (O for the mask overlay,
caught by mask_adjustments_hide_overlay_without_disabling_the_mask). Now a selected slider owns
the arrow keys only. The wheel test opens the Edit panel explicitly (the demo may start on it, and
panel.edit then toggles it shut), and the Export dialog snapshot is 546 px wide since #833's
nine watermark positions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
photo.editExternal takes the selection (or ids, at most 50): each photo gets its own -Edit copy
stacked on its original, the copies are selected and returned in copies (path / id / original
still name the first). Photo ▸ Edit In opens each copy in the editor.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
On merge: Lightroom's default profiles (Adobe Standard, Adobe Color), named by nearly every sidecar,
give no camera-profile warning; other profiles still do (test default_lightroom_profiles_are_not_reported).
The import help string keeps main's onDeleted wording and gains warnings.
On merge: the quick preview path orients like the whole-file path (preview_orientation with the
raw's header prefix, so a portrait raw whose embedded JPEG carries no orientation is not sideways),
and its doc links point at preview_window.
- Settings ▸ General ▸ External Editing: the PhotoCraft location and Other editor
fields move from egui::TextEdit to TextField (edit menu, Esc restores).
- Edit In with the system default on Windows starts explorer.exe with the file
as one argument instead of cmd /C start, which read & ^ % | in file names as
shell syntax.
- psd::packbits walks the row with first()/get()/split_at_checked instead of
direct indexing and slicing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
move_across_volumes read both whole files into memory to compare them; it now
compares lengths first, then streams 1 MiB chunks. The grid's Move to Folder…
asks through pick::ask (background dialog where the host has one) like the
other folder pickers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4