Input Key Selector: selected chord, capture events, cancel, and conflict handoff¶
At a glance
Selected value: FInputChord—one FKey plus Shift, Ctrl, Alt, and
Command modifier flags ·
Capture state: Get Is Selecting Key and
On Is Selecting Key Changed ·
User candidate event: On Key Selected(FInputChord) ·
Cancel: Escape and configured Escape Keys end capture without proposing
a new key ·
This widget does not: find conflicts, change an Input Mapping Context,
apply a player mapping, or save it ·
Official pages: Input Key Selector ·
Input Chord ·
Slate Input Key Selector
The one-minute version¶
- Input Key Selector is a capture control. It displays one selected
FInputChord, enters a temporary listening state, and reports a new chord chosen by the user. - An
FInputChordis one coreFKeywith optional Shift, Ctrl, Alt, and Command flags. It is not an Input Action, an Input Mapping Context row, an input sequence, or a saved Enhanced Input binding. On Is Selecting Key Changedtells you that capture started or stopped. ReadGet Is Selecting Keyfor the current state. It does not tell you why capture stopped.On Key Selectedis the candidate event. It means the widget accepted a chord from the user; it does not mean the project's rebinding model accepted, applied, or persisted it.- Snapshot the prior chord before capture. If capture stops without a candidate, leave the draft unchanged and repaint that prior value.
- Decide up front whether keyboard modifiers and gamepad keys are valid. The
stock Enhanced Input player-mapping request takes one
FKey, not anFInputChord; never enable modifier capture and then silently discard the modifier flags. - Send the candidate to one settings/rebinding owner. That owner checks the mapping name, profile, slot, device policy, reserved keys, and conflicts, then returns the authoritative value for the widget to display.
- Treat capture as a small modal interaction: one selector at a time, clear feedback, deliberate cancel keys, and focus restored for the correct local player.
What it actually does¶
The UMG UInputKeySelector wraps Slate's SInputKeySelector. Its public value
is Selected Key, an FInputChord; its temporary interaction state is
Is Selecting Key.
pseudocode — UI state, not engine source
Idle: display SelectedKey
activate selector
Capturing: display KeySelectionText and listen for an allowed candidate
accepted candidate -> Idle + OnKeySelected(CandidateChord)
cancel/abandon -> Idle + no new candidate
Do not turn Is Selecting Key = false into “the rebind succeeded.” Both an
accepted candidate and a cancellation end the listening state. Only the
candidate event supplies a proposed new chord, and only the rebinding model can
decide whether that proposal becomes a setting.
FInputChord, FKey, and a player mapping are different values¶
FInputChord contains these fields:
| Field | Meaning |
|---|---|
Key |
The one core FKey, such as E, Left Mouse Button, or a gamepad face button |
bShift |
Shift must be held with the core key |
bCtrl |
Ctrl must be held with the core key |
bAlt |
Alt must be held with the core key |
bCmd |
Command must be held with the core key |
Its Get Input Text function produces localized display text for the chord.
That is useful for a text label, but it is still only a display representation;
do not persist the rendered Text as key identity.
The nearby types answer different questions:
| Value | Answers | Does not contain |
|---|---|---|
FKey |
“Which physical/logical key or button?” | Modifier flags, mapping identity, slot, or profile |
FInputChord |
“Which one key, with which standard modifiers?” | Input Action, trigger logic, context, profile, or save state |
| Enhanced Input player-mapping row | “Which player-mappable mapping name and slot currently use which FKey?” |
The selector's capture state or an automatic conflict decision |
This distinction matters for modifier chords. Current Enhanced Input
FMapPlayerKeyArgs sends a New Key of type FKey. If the game really supports
Ctrl+E as a player binding, model that design explicitly—through project input
logic, triggers, or a project-owned chord layer. If the screen only edits stock
Enhanced Input player mappings, turn Allow Modifier Keys off. Dropping
Ctrl and submitting only E changes what the player chose.
Selected value, selecting state, and user candidate¶
Use the three surfaces for three separate jobs:
| Surface | What it means | Good use |
|---|---|---|
Get Selected Key / Selected Key |
The chord currently displayed by this widget | Repaint and accessibility text |
Get Is Selecting Key |
Whether temporary capture is active now | Show/clear a capture overlay and suppress competing menu actions |
On Is Selecting Key Changed |
Capture entered or left a state | Re-read Get Is Selecting Key; restore presentation when it becomes false |
On Key Selected(NewChord) |
The user supplied a new candidate chord | Ask the rebinding owner to validate the candidate |
On Is Selecting Key Changed is a transition notification rather than a
commit event. Its UMG delegate does not provide a selected chord or a cancel
reason. Keep your own small capture record instead of trying to reconstruct
intent from event order:
ST_KeyCapture
bActive: bool
MappingName: Name
Slot: PlayerMappableKeySlot
BeforeChord: InputChord
bCandidateReceived: bool
When capture begins, store BeforeChord and mark the row active. When
On Key Selected arrives, mark that a candidate was received and hand it off.
When selection state returns to false without an accepted candidate, clear the
capture record and repaint from the authoritative draft.
Cancel, Escape Keys, and no-key state¶
In the UMG Input Key Selector, Escape is the normal cancellation path.
Escape Keys adds other FKey values that should behave as cancellation keys
instead of becoming bindings. That is useful for a controller Back button, but
it is also a product decision: a key listed there cannot be selected through
that control.
The lower-level Slate widget has an Escape Cancels Selection construction
setting. The 5.8 UMG wrapper exposes Set Escape Keys, but not a Blueprint
setter for that Slate Boolean. If the game must let players bind Escape itself,
the ordinary Designer widget is not enough; use a project wrapper with an
explicit escape policy and test menu Back behavior with it.
On cancel:
- do not dirty the options draft;
- do not run conflict handling;
- keep the last accepted mapping as the authoritative value;
- clear “press a key” presentation; and
- restore user focus to a deliberate row or button.
An invalid/default FInputChord has no usable core key and can represent an
unassigned display state. Give that state an explicit label such as
“Unbound.” Do not confuse cancel capture with clear this binding. A
separate Clear action should ask the settings model to unmap the row and should
be validated like any other edit.
Modifier, gamepad, and capture policy¶
Modifier keys¶
With Allow Modifier Keys enabled, the selector records supported modifier
state on the captured chord. With it disabled, modifier flags are ignored.
Modifiers decorate one core key; FInputChord is not a multi-key combo or a
sequence such as “Q, then E.”
Choose one policy and say it in the UI:
- single-key Enhanced Input bindings: disable modifiers;
- project-owned chord bindings: enable them and preserve all flags through validation, conflict checks, persistence, and runtime evaluation; or
- mixed support: expose it per action and reject unsupported candidates with a specific explanation.
Gamepad keys¶
Allow Gamepad Keys controls whether gamepad keys may become the selected chord. If it is off, gamepad input is ignored for selection; that can make a controller-driven capture screen appear stuck unless the UI explains the policy.
A controller also uses buttons and directions for menu navigation. While capture is active, an Accept, Back, or navigation input may instead be the candidate or cancel signal. Test the actual controller path and decide:
- which button starts capture;
- which button cancels;
- whether navigation keys/buttons are legal bindings; and
- how focus returns after capture.
Input Key Selector handles keyboard keys and mouse buttons through its Slate
input routes, but it is not a universal “learn any input” control. Analog
values, axis direction policy, gestures, holds, double-taps, and trigger
semantics belong to the input model rather than to FInputChord.
Programmatic initialization is not a user edit¶
Set Selected Key updates the widget's presentation. On Key Selected is
documented for a new key selected by the user; do not call the user handler
by hand after initialization.
Use the same guarded model-first pattern as the rest of an options screen:
pseudocode — Blueprint screen flow
OpenBindings(LocalPlayer)
-> bInitializing = true
-> Draft = RebindingCoordinator.OpenDraft(LocalPlayer)
-> for each binding row:
Selector.SetSelectedKey(Draft.DisplayChordFor(RowId))
-> bInitializing = false
-> bDirty = false
OnKeySelected(RowId, CandidateChord)
-> if bInitializing: return
-> RebindingCoordinator.ProposeCandidate(RowId, CandidateChord)
Selected Key is also field-notify capable, so property bindings can repaint
when it changes. Do not combine a binding and manual setters unless one owner
defines which wins; two presentation owners make a rejected candidate appear
to “come back” unpredictably.
Conflict presentation belongs to the settings model¶
The selector knows only the chord it captured. It does not know whether two Input Mapping Contexts can be active together, whether a key is reserved, or whether the product allows duplicates. Those are domain rules.
Send a typed request that preserves identity:
ST_RebindCandidate
LocalPlayer
ProfileId: String
MappingName: Name
Slot: PlayerMappableKeySlot
HardwareDeviceId
CandidateChord: InputChord
The coordinator can then validate in this order:
- Confirm that the local player, profile, mapping name, slot, and candidate are valid for this screen.
- Convert the candidate without losing information. Reject unsupported
modifier chords instead of flattening them to
FKey. - Query mappings that already use the candidate key, then filter them by the contexts/device rules that can actually conflict.
- If there is a real conflict, present the project's choices—commonly Replace, Swap, Keep Both, or Cancel.
- Only after that decision, update the draft mapping and return the authoritative chord to every affected row.
“This key appears elsewhere” is not automatically a conflict. The same key may be intentional in mapping contexts that cannot be active together. Conversely, a reserved menu key can be invalid even when no other gameplay row uses it.
Keep the conflict dialog transactional. If the player cancels it, repaint the selector from the old draft. If Replace or Swap changes another row, repaint both rows from the model rather than editing two widgets independently.
See Enhanced Input User Settings: map, unmap, reset, apply, and save for the mapping/profile operations that receive an accepted single-key edit.
Focus, navigation, and lifetime¶
- Set user focus for the initiating local player, not global keyboard focus or an assumed player-zero widget.
- Allow only one active capture per screen. Starting a second selector should explicitly cancel or finish the first capture record.
- While capturing, suppress competing screen shortcuts that would consume the candidate before the selector or execute an unrelated action as well.
- Focus loss and screen removal are abandonment paths, not successful edits.
Only
On Key Selectedsupplies a candidate; clear any screen-owned capture state when the row or screen goes away. - Restore focus after candidate acceptance, selector cancel, conflict-dialog cancel, and conflict resolution. Each path matters for controller users.
- Keep an accessible prompt visible while selecting and announce the accepted or rejected result; changing button text alone can be easy to miss.
See Set Keyboard Focus / Set User Focus / Set Is Enabled for local-player focus and recovery.
When it fails (and what failure does)¶
Input Key Selector has no “rebind succeeded” Boolean or failure execution pin:
- a disallowed gamepad key is ignored and capture can remain active;
- Escape or an Escape Key cancels rather than selecting that key;
- an abandoned/focus-lost capture supplies no accepted candidate;
- an invalid chord has no usable core key;
- an allowed modifier chord can still be unsupported by the downstream Enhanced Input mapping model;
- a candidate can be rejected by reserved-key or conflict policy; and
- a widget reference can be
Noneafter its screen is removed.
None of those outcomes automatically logs, rolls back a settings draft, saves, or tells another row to repaint. Retain the last accepted draft, give capture a visible timeout/cancel route where appropriate, and make the coordinator return a concrete rejection reason.
What this widget does not do¶
- It does not edit an Input Action or Input Mapping Context asset.
- It does not call
Map Player Key,UnMap Player Key, reset, apply, or save. - It does not discover player-mappable mapping names, slots, or profiles.
- It does not decide whether duplicate keys are legal.
- It does not preserve modifier chords through an
FKey-only API for you. - It does not replicate a local player's binding to the server or other players.
- It does not create glyph art or switch visual prompts by input device.
Lookalikes — which one do I want?¶
| Type / system | Use it when | Do not confuse it with |
|---|---|---|
| Input Key Selector | A UMG row must capture and display one key/chord candidate | A rebind/save system; it only owns the interaction |
FKey |
An API needs one key identity | FInputChord, which can also carry standard modifier flags |
FInputChord |
UI/command input needs one key plus modifiers | An Enhanced Input action, trigger graph, or multi-key sequence |
| Input Action | Naming a gameplay intent and evaluating its value/triggers | The player's chosen key |
| Input Mapping Context | Declaring action-to-key mappings active in a gameplay context | A runtime per-player profile or capture widget |
| Enhanced Input User Settings | Mapping, unmapping, resetting, applying hooks, and persistence per local player | The selector's listening state |
| Project/CommonUI key display | Device-specific glyphs and rich prompt presentation | Key capture; display systems need not edit bindings |
Going deeper¶
- Enhanced Input User Settings: map, unmap, reset, apply, and save — accept a validated single-key candidate into a local player's profile.
- Options/settings screen architecture — keep captured, draft, applied, and persisted state distinct.
- Set Keyboard Focus / Set User Focus / Set Is Enabled — local-player focus and controller recovery.
- Input Key Selector, Input Chord, and Slate Input Key Selector — current public API and event/property contracts.
- Engine source (requires engine access; we do not reproduce it):
UInputKeySelector::RebuildWidget,SynchronizeProperties,HandleKeySelected, andHandleIsSelectingKeyChangedinEngine/Source/Runtime/UMG/Private/Components/InputKeySelector.cpp;SInputKeySelector::OnKeyDown,OnKeyUp,OnMouseButtonDown,OnNavigation, andOnFocusLostinEngine/Source/Runtime/Slate/Private/Widgets/Input/SInputKeySelector.cpp; andFInputChord::GetInputTextinEngine/Source/Runtime/Slate/Private/Framework/Commands/InputChord.cpp.