The Keyword Set menu gets Edit Set… (Lightroom Classic's Edit Keyword
Set): the set's name and its nine keywords, one field per ⌥ key, typed
in place. Editing Recent Keywords and naming them saves a new set and
makes it current; editing a named set renames it in its place. An
empty field is an empty slot, shown as an idle button so the others
keep their keys. Return in any field saves; a set without a name says
so and the dialog stays open. Russian gets "Set name", and the label
check covers the new labels.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lightroom Classic's Keywording box has three views; the box had two.
The switch now offers Keywords, & Containing (the selection's keywords
with the keywords containing them, flat and read only) and Will Export,
the two read-only views cached per selection. The label check covers
the box's other labels passed through variables too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The box emptied itself on Esc, on top of the shared field's own undo of
the edit: text left there by an earlier edit (ended by clicking away)
went too. Esc now gives back what the box held before the edit, as
every text field does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`chips_stay_on_one_line` held by construction once chips were drawn at
a fixed height with their × on their own line. It now checks that every
chip is on one line inside the panel and that none overlaps another,
with a keyword longer than the panel among them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drawn as one widget, a chip and its × lost the names a button gave
them: screen readers met unlabeled buttons. The chip is now named after
its whole keyword (even when cut short on screen) and the × "Remove
“…”". Both answer under ids made from their keyword rather than their
place in the row, so a chip's open menu stays with its keyword when the
chips change underneath it (an undo, a sync).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A photo listed twice in the selection counted twice, and an id the
library doesn't have counted in "of": the chips, Will Export and the
Keyword List's tick boxes now count the distinct selected photos.
- The chips looked each keyword's spelling up by scanning every photo
(178 ms with 20,000 photos and 2,000 keywords selected, at every
change while selected): they now take the keyword list's spelling
(`Catalog::listed_path`) or the first one seen, 26 ms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A chip too long for its row was cut with the file-path shortener, which
keeps the start: "Places › Portugal ›…" lost the keyword's own name and
the asterisk of a partial one. `chip_label` now cuts from the front
("…Lisbon › Belém tower *"). A chip also had two tooltips (its whole
name, and how many selected photos have it); it has one with both.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keyword commands act on the selected photos, or on the active photo
when the selection is empty (`Session::targets`), but the Keywording
box, the keyword set's buttons, the suggestions and the Keyword List's
tick boxes read the selection only: with just an active photo the box
showed nothing while typed keywords went to it. They now all use the
photos the commands use.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A chip was a frame laid out in what was left of its line: one that
didn't fit wrapped its own text, down to a letter a line, and pushed
its × to the next line. A chip is now one widget measured before it is
placed (its name cut short to fit the row), so the row moves it whole
to the next line; the Will Export names alike.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Suggestions were worked out from the active photo's keywords: a keyword
it had wasn't suggested though other selected photos lacked it. They
now leave out only the keywords every selected photo has, and build on
those for keywords used with them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Keyword to paint" gets the Cut / Copy / Paste / Select All menu and
Esc, and Return starts painting as the Paint button does. It stays
fixed while painting.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lightroom Classic's Keywording box can show the keywords that will be
exported rather than those entered. A Keywords / Will Export switch
under the box now does the same for the selection: the names exported
files carry as the keyword tag options say (a keyword left out of
export goes, parents and synonyms come), one only some of the photos
carry marked with an asterisk. Read only; cached per selection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The nine buttons showed "on" when the active photo had the keyword,
while their ⌥1–⌥9 toggle acts on every selected photo. A button is now
on when every selected photo has its keyword, and marked with an
asterisk when only some do, as the chips are.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It gets the Cut / Copy / Paste / Select All menu (paste a list of
keywords from elsewhere), Return gives the keywords to every selected
photo as before, and Esc gives up what was typed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The chip menu offered Delete Keyword, which takes the keyword off every
photo in the library, beside "Remove from Photo". It now acts on the
selected photos only: Add to All Selected Photos (for a keyword only
some have), Remove from Selected Photos, Show Photos with Keyword, and
Edit Keyword Tag… (the Keyword List's dialog, for renaming too).
Deleting a keyword from the library is the Keyword List's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The chips at the top of the Keywords panel showed the active photo's
keywords, while adding and removing applied to every selected photo:
with several selected they misreported what the selection had. They
are now the keywords of every selected photo, each once whatever its
case (`panels::keywording`, cached per selection), and one only some
of them have is marked with an asterisk ("On 1 of 2 selected photos").
Only the × removes a keyword, from every selected photo: a click on
the chip itself used to remove it too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With nothing selected a tick box still offered "Add to Selected
Photos", and while a filter holds the levels open the triangle lit up
on hover though a click does nothing. Neither does now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The toast said every dropped photo got the keyword, those that had it
already included. It now counts the photos that didn't have it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lightroom Classic puts new keywords typed for photos inside the keyword
marked Put New Keywords Inside This Keyword; only + did here. The
Keywords panel's box now does too (`Catalog::typed_keyword`): a new
name goes inside the default parent, while a keyword the library has,
or a path typed whole, stays as typed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Russian had no "Person": the option showed in English (it reaches
`tr` through a variable). A test now checks that every label the
Keyword List passes that way is in every language's file.
- The merge confirmation's button said "Merge", which some languages
translate as merging photos (HDR, panorama): it says "Merge Keywords".
- Traditional Chinese uses 匯出 for Export, as everywhere else in the
file, not 轉存; "Export Containing Keywords" means the parent
keywords in both Chinese files (上層 / 上级), not "included" ones.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Keyword List ended a keyword drag only while it was drawn: with
another panel opened mid-drag, the drag lingered until the list came
back. `keyword_list::drag_feedback` now runs every frame, like the
album drag's: the drag ends with the button's release wherever it is,
or with Esc. A press on a tick box that moves no longer picks the
keyword up. The test that a keyword can't be dropped inside itself
now checks that no move was even tried.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After a rename (Edit Keyword Tag), a drag or a merge made in the list,
the picked keyword still named the old path (the highlight went and −
was greyed out for a keyword that was there) and the renamed levels
closed. The pick and the open levels now follow the keyword, and the
levels containing it open, so a keyword dropped into another stays in
sight.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In Create / Edit Keyword Tag only the name field answered Return: typed
synonyms followed by Return did nothing. Return in Synonyms now creates
(or saves) the keyword too, as a dialog's default button does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With no photo active the whole right panel said "No photo selected",
so the library's Keyword List disappeared: keywords couldn't be made
or organized before choosing a photo. The Keywords panel now shows the
list without a selection (its tick boxes wait for one), under a note
that selecting photos gives them keywords.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Keyword List took a drop wherever the pointer was inside a row's or
the title's rectangle, even where the panel had scrolled it out of
sight: a keyword released over the app's top bar, where the list's
title was hidden, went to the top level. Drops now need the pointer on
the visible part of the panel too; photos dropped from the grid alike.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every row worked out its tick box from every selected photo's keywords,
every frame: with 20,000 photos selected a frame took seconds. `Ticks`
now counts each keyword over the selection once, cached by library
revision and selection, and each row looks its count up: 2.8 ms a
frame for 20,024 selected photos. The check that the picked keyword
still exists reads the cached tree instead of scanning every photo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Put New Keywords Inside This Keyword" was a session preference that
followed renames by hand: undo and redo never moved it back, so after
undoing a rename it named a keyword that no longer existed and the
next new keyword silently made that parent again. It is now a mark on
the keyword in the catalog's keyword list (`new_keywords_inside`, one
keyword at most): it moves with its keyword (into a merge too), goes
with it, comes back with undo and redo, and is kept with the library.
Setting it is one undo step.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In the Keyword List:
- dragging a keyword onto another nests it there, with the keywords
below it and its photos; dropping it on the list's title (which
says "Drop here for the top level" during the drag) takes it to the
top level;
- a keyword is never outlined, nor dropped, inside itself or one of
its children;
- where a keyword of its name is already, a dialog asks before merging
the two;
- photos dragged from the grid onto a keyword get it.
The dragged keyword's name follows the pointer; the drag ends with the
button's release, wherever it is.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Right-clicking a keyword offers Create Keyword Tag Inside it, Edit
Keyword Tag, Put New Keywords Inside This Keyword (the list marks that
keyword with a dot), Add to / Remove from Selected Photos, Show Photos
with Keyword, Purge Unused Keywords and Delete Keyword.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The + button opens Create Keyword Tag: a name, synonyms, "Put inside"
the keyword picked in the list (or the default parent), "Add to
Selected Photos", and the keyword tag options (Include on Export,
Export Containing Keywords, Export Synonyms, Person). Return creates
it; a name that is taken says so and keeps the dialog open.
- Double-clicking a keyword opens Edit Keyword Tag with its name and
attributes; a new name and options apply in one undo step.
- The − button deletes the picked keyword after saying how many photos
lose it.
The name takes the focus once when the dialog opens: the one-field
dialogs' `dialog_field` takes it back every frame, which would steal it
from Synonyms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Keywords panel ends with Lightroom Classic's Keyword List: every
keyword of the library, those without photos too, as a tree with photo
counts (`panels::keyword_list`).
- A filter box keeps the keywords whose name holds the text, with the
keywords containing them opened down to them.
- The triangle opens a level (kept with the UI state).
- The tick box says whether every, some (a dash) or none of the
selected photos have the keyword, and gives it to all of them or
takes it away.
- The arrow shown on hover shows the photos with the keyword.
- A click picks a row, for the actions that follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New Album, Rename Album, New Smart Album, Merge Keywords and the text
prompts (rename a preset or a version, …) had Rename Keyword's bug:
their field took the focus back on every frame, so egui never reported
the focus Return gives up, and Return did nothing; only OK confirmed.
All six now use one `dialog_field`: a shared text field that keeps the
focus except while its own menu has it, opens with its text selected
and reports Return. They get the Cut / Copy / Paste / Select All menu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It gets the Cut / Copy / Paste / Select All menu and opens with the
name selected, so typing replaces it. Return now renames: the field
took the focus back on every frame, so egui never reported the focus
Return gives up and only the OK button renamed. The field still keeps
the focus, except while its own menu has it; Esc still cancels the
dialog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Title, Caption, Alt Text, Extended Description, Copyright, the usage
terms, the creator and the place fields get the Cut / Copy / Paste /
Select All menu. Esc now gives an edit up: it used to save the typed
text, since the field saved whenever it lost the focus. The caption and
other multi-line fields keep taking Return as a new line and save on
leaving; the shared field gains `rows` for them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What's New and the KEY-CLIPBOARD row overstated the Windows / Linux
fix: Ctrl+V reaches the app only while the system clipboard holds text
(egui-winit drops it otherwise), and it never worked before, so not
"again". The text field's module doc says what it depends on, that its
widget id must be unique on screen, and that new text boxes use it; MCP
`click` lists `button`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With no text field focused, `ui.clipboard` (and MCP `clipboard`) sent
the clipboard event to the app's shortcuts: it pasted edit settings on
Windows, Linux and in headless runs, and did nothing on macOS, whose
menu bar takes ⌘V. It is now refused there; agents run `develop.copy`
and `develop.paste` instead. The docs also say that cut and copy write
the system clipboard in the desktop app.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
egui-winit also sends a paste for Windows' Shift+Insert (and a cut for
Shift+Delete): read with the Shift held, it matched ⇧Ctrl+V and opened
Paste Selected Settings. A clipboard event with no Ctrl/⌘ held is now
the plain command.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Select-on-focus selected everything on the press that took the focus,
after egui had placed the drag's anchor there: a drag then selected
from the start of the text. With a press, the field now waits for the
release and selects everything only after a plain click, as a
browser's address bar does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A field hidden while its menu had the focus (its panel collapsed, its
slider turned off) came back with that state: it reported a spurious
Away when shown again, kept the text from before an edit that was cut
short, and would have replayed a menu choice picked on its last frame.
A field not drawn in the previous frame now starts afresh.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`Response::has_focus` is false while the window is in the background,
so switching to another app mid-edit forgot the text from before (Esc
then gave back the half-typed text), a select-on-focus field selected
everything again on coming back, and `editing` went false: a slider's
typed value applied and closed. The field now follows egui's own focus,
which the window's doesn't change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Return with the menu open left the edit hanging (the field gave up the
focus, taken for a click in the menu) and it ended later as Away: a
name field that submits on Return never submitted. It now ends the edit
as Return and closes the menu. Esc with the menu open, or with the
focus in the menu, cancelled the whole edit; it now closes only the
menu, as native menus do, and the field takes the focus back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The field's menu closed on any click, a greyed-out Cut or Copy too, and
the press had already taken the focus: the edit ended as if the user
had clicked away (a slider applied its half-typed value). The menu now
closes only on a choice or a click outside it. The test that said Cut
and Copy need a selection could not fail (egui copies nothing from an
empty selection anyway); it now checks the greyed-out items.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
egui-winit turns Ctrl+C / Ctrl+X / Ctrl+V (with any other modifiers)
into clipboard events and drops the key press, so outside text fields
Copy Settings, Paste Settings and ⇧Ctrl+V (Paste Selected Settings)
never fired there; macOS was spared because its menu bar takes ⌘C / ⌘V
first. The shortcuts now read those events as the keys they were, as
the keymap editor already did when recording a shortcut.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It gets the Cut / Copy / Paste / Select All menu, and Esc in it now
clears the selection as Clear does, as the code meant: it checked the
field's focus on the Esc frame, which egui has already taken away, so
Esc only left the field.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The value typed after clicking a slider's number gets the Cut / Copy /
Paste / Select All menu (`sliderField:<control>`), and using the menu no
longer closes the field: it used to close as soon as anything took the
focus. Selecting the old value and Esc now come from the shared field;
`TextFieldResponse::editing` says an edit is under way, the menu
included.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Search Photos gets the Cut / Copy / Paste / Select All menu, and Esc
gives back the search from before the edit (and filters by it again).
The field gains the builder options it needs (no frame, font, colour,
alignment, margin) and `text_field::id` for ⌘F to focus it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`ui.click` took `button`, `ui.clickWidget` ignored it: MCP `click
{widget, button: "right"}` passes it on, and silently left-clicked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`ui.clipboard {action, text?}` does what the system does for ⌘X / ⌘C /
⌘V in the focused text field (egui-winit sends clipboard events, not
key presses, so `ui.key` with ⌘C could not), and `ui.inspect` reports
`copied`, the text the UI last put on the clipboard. MCP has the same
as the `clipboard` tool when the app is attached.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`text_field::TextField` is a standalone text field for every text box in
the app:
- right-click for Cut, Copy, Paste and Select All, shortcuts shown,
acting on the selection the right-click would otherwise move (the
browser build has no Paste item: a page cannot read the clipboard on
request);
- Esc gives back the text from before the edit, also after using the
menu;
- the caller learns how an edit ended (Return, focus away, Esc) and
decides what that means; using the menu is not leaving the field;
- optionally everything is selected when it takes focus;
- an edit cut short when the field goes away is forgotten.
The menu replays egui's own Cut and Copy events and asks the host for a
paste, so passwords, character limits and undo work as egui does them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Text the UI copies lands in `HeadlessView::clipboard`, and a cut, copy
or paste request (`ViewportCommand::RequestCut/Copy/Paste`) comes back
as that event on the next frame, as egui-winit does on the desktop. UI
tests can now check copying and pasting in text fields.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>