The keyboard pane (Options::keyboard) draws a US ANSI layout under the
table and detail pane, coloured by who holds each key with the toggled
and held modifiers, lists the clicked key's shortcuts and assigns key and
modifiers to the selected command. Fixed rows always report a label, with
"Now used by" when a command took their key. A read-only dialog has no
set row, keeps Summarize in the footer and closes with shortcuts.close.
Set row with picker, New Set (based on current shortcuts or a set),
Rename, Delete, Save, Revert Set, Export, Import and Summarize; actions
that do not fit go into a More menu. The foreign import review lists
what will change, suggestions to pick, unmatched, unreadable,
approximated and matched-without-change entries, then the report of
skipped, taken and failed changes with Copy Report. ui::summary writes
the shortcut summary as HTML and plain text.
- view.rs: header with Show (dropdown or tabs), Filter and Search with search
by key; table and detail pane in a resizable split, the detail pane below
the table under 720 pt; virtual rows with chips, + and the restore button;
detail pane with current shortcuts, New Shortcut, typed entry, Context,
Assign, Use Default and Clear; prompts, conflict bar, messages, clash,
shadow and problem lines; Undo, Redo, Reset All, Cancel and OK.
- Escape, Enter, Undo and Redo keys when idle; table keys (arrows, Home,
End, Enter records, Delete removes); focus locks while recording.
- Accessibility labels for every control, row selection, and on_widget
automation ids.
- style.rs: DialogStyle and the icon-button and divider styles.
- show() sizes the window to the screen; closing it is Cancel.
- tests/ui_dialog.rs: recording, conflicts, search, areas, display, labels,
table keys, small windows, RTL. tests/ui_snapshot.rs (feature snapshot)
writes PNGs when CRAFT_KEYMAP_SNAPSHOT_DIR is set.
Profiles keeps the user's sets beside the app's built-in ones: switch, duplicate,
rename, delete, export one set as JSON and import it back, and import another
application's set through an import plan as a new set. The editor model holds an
edit session with undo and cancel, conflict queries for steal or keep, a chord
recorder with double press, and search.
The last segment of a panel-menu entry matches alone only when the panel
name is a segment of some catalogue path. An entry without keys matched
only as a panel-menu item leaves the command's shortcuts alone and is
listed in ImportReport::matched_without_change. Tests cover an entry
without keys next to one with keys for the same command, in both orders.
- ForeignEntry::in_panel_menu marks an item whose leading segments name a panel
(InDesign's "Character: All Caps"); it also matches a catalogue path ending
with its segments, then its last segment as a unique label.
- Aliases count in the menu steps too, joined segments are tried as a label or
alias anywhere, and normalize_label reads a colon as a space, so the alias
"Preferences: General…" matches "Edit > Preferences > General...".
- A leading Show, Hide or Show/Hide is dropped only for commands marked
Bindable::toggle, and only after the names as written found nothing.
- Keys in skipped contexts are left out of unmatched rows, so entries with only
such keys no longer use up the suggestion cap.
reset, and an edit that leaves a command with its defaults, removed
only the entry the command read. A variant of its key
(window.panel { "panel": "layers" }) stayed and took effect on the
next load. Both remove every entry that resolves to the command.
conflicts_with lists the commands that share one command's chords, with
that command as a, without filtering every conflict. The README shows
set_bindings with one binding for an editor with one shortcut per
command; assign adds a binding.
Apps that stored { command: text } before read the field in older builds
again. Overrides with several bindings for a command still serialize as
the { command, keys } array. keymap::overrides_list always writes the
array, for craft-settings files, where only an array lets a reset entry
leave the file.
Hit carries the trigger that matched and whether the press matched it
exactly. Dispatcher::dispatch_filtered takes a predicate; a declined hit
leaves its event and text in place.
egui's Copy, Cut and Paste events stay with the app unless
with_clipboard_events(true): egui-winit sends them in place of the
clipboard presses, and a Paste event consumed as a hit lost its text.
With them on, Hit::pasted holds that text, and a web clipboard press
and the event it causes run once for every clipboard chord, not only
Cmd+C/X/V. The Hit doc line moves from DOUBLE_PRESS to Hit.
craft-keymap holds the data and logic for keyboard bindings: egui-free
chords with one canonical text form, bindings to commands with params,
several bindings per command, scopes, tool groups, conflicts, overrides
kept in a craft-settings type, an import pipeline for other applications'
shortcut sets, and an optional egui dispatcher. Apps keep their command
catalogue, file readers and UI.