Set Keyboard Focus / Set User Focus / Set Is Enabled¶
At a glance
Lives on: any UMG Widget - Set Keyboard Focus: requests focus
through Slate's keyboard-focus route - Set User Focus: requests focus
for the local user identified by a Player Controller - Set Is Enabled:
allows or blocks normal interaction while keeping the widget in layout -
Returns: no success value from any of the three nodes - Can fail by:
targeting None, focusing a widget that is not constructed, present,
visible, enabled, or focusable, or supplying the wrong/non-local controller -
Official docs:
Set Keyboard Focus,
Set User Focus,
and
Set Is Enabled
Focus answers which control receives keyboard/gamepad UI input for a user. Enabled state answers whether a widget and its descendants may interact. Neither one displays the menu or changes the Player Controller's input mode.
The one-minute version¶
- Slate tracks a focus path for each local user. Only one widget at the end of that user's path owns focus at a time.
Set Keyboard Focushas no Player Controller input. It uses the application's keyboard-focus route; it does not mean "focus this for all split-screen players."Set User Focustakes a Player Controller and changes focus for that controller's local Slate user. Use it when the player must be explicit.- If the target belongs to its intended owning player, the
Set Focusconvenience is preferred by Epic because it selects that owning user. - A focus request needs a live Slate widget in the active widget hierarchy, and the target must support keyboard focus. Add/show/enable the menu before focusing its first Button or focusable User Widget.
Set Is Enabled(false)keeps the widget painted and in layout but blocks normal interaction. Controls often draw a disabled style; custom widgets may look unchanged unless you style them.- Disabling a parent effectively disables every descendant. A child can still store its own enabled flag, but it cannot escape a disabled ancestor.
- Hiding, disabling, or removing the focused widget does not define a useful replacement. Move focus deliberately to the modal's first control, the previous menu control, the next enabled option, or back to gameplay.
- Input mode, focus, cursor, visibility, enabled state, and widget lifetime are separate parts of opening and closing a menu.
Focus is a path for one user¶
Focus is not a Boolean that every widget can turn on independently. Slate stores a path from the active window through the widget hierarchy to one focus target for each user:
local user 0 focus path
game window
`-- Player 0 screen
`-- PauseMenu
`-- ResumeButton <- focused widget
local user 1 focus path
game window
`-- Player 1 screen
`-- Inventory
`-- UseButton <- focused widget
When one target receives focus for a user, the old target on that user's path loses it. Player 0 and Player 1 can have different focused controls in local multiplayer.
Focus is what lets a Button respond to Enter/gamepad Accept, an Editable Text control receive typed characters, and directional navigation know where to start. It is not the same as pointer hover, mouse capture, selected list item, or the Player Controller's gameplay input routing.
Set Keyboard Focus versus Set User Focus¶
Both Blueprint nodes target a Widget and return no success/failure value.
They differ in how the user is chosen.
Set Keyboard Focus¶
Set Keyboard Focus supplies only the target widget. Underneath UMG, it asks
Slate to change the application's keyboard focus to that widget.
That is convenient in a single-user game or an application screen where the keyboard owner is unambiguous. It is a poor selector for local multiplayer: the node does not carry a Player Controller, local-player index, or "all users" instruction. Which Slate user owns the physical keyboard route is an input/application mapping concern, not information encoded in this node.
Use it when the application keyboard focus is exactly what you mean. Do not read "Keyboard" as "Player 0" or "every local player."
Set User Focus¶
Set User Focus takes a Player Controller. UMG uses that local controller to
identify the corresponding Slate user, then requests focus for only that user.
The controller must represent a local player on this machine. A server-only controller or a remote controller representation has no local screen/input user to focus. In split-screen, pass the same controller that owns the widget and whose player-screen section displays it.
Player1Controller
-> Create Widget(Owning Player = Player1Controller)
-> Add to Player Screen
-> FirstInventoryButton Set User Focus(Player1Controller)
Do not call Get Player Controller 0 from every widget. That makes every
local menu compete for user 0's focus even when the widget belongs to another
player.
Set Focus: the owning-user convenience¶
Set Focus targets the widget without a controller pin, but its contract is
different from Set Keyboard Focus: it selects the widget's owning user.
Epic's current UWidget API recommends it when that is the user you mean.
For that to be reliable, create the root User Widget with the correct Owning
Player, keep child controls inside that owned widget hierarchy, and use
Add to Player Screen for split-screen presentation. Use explicit Set User
Focus when code outside the widget is selecting a particular local player.
What a focus request needs¶
A valid UObject reference is necessary but not sufficient. The target needs a usable Slate focus path.
1. The underlying widget must exist¶
UMG objects wrap Slate widgets. A freshly allocated object that has not built its Slate representation cannot become the active screen focus target. Adding the root User Widget to a viewport/player screen builds and registers the visible hierarchy.
For normal menus:
Create Widget
-> Add to Player Screen / Add to Viewport
-> make panel Visible and enabled
-> set input mode
-> focus the first real control
Calling focus before the hierarchy is present usually does nothing useful; there is no pending success pin or automatic retry.
2. The widget must support keyboard focus¶
Not every Widget is a focus stop. Buttons, text-entry controls, and other
interactive widgets can support focus. Decorative Images and Text Blocks
normally should not. A root User Widget has an Is Focusable setting when you
intend the root itself to handle keyboard events.
Supports Keyboard Focus is the direct query when debugging. If a menu root
is only a container, focusing its first Button is usually clearer than making
the whole root focusable.
Current UE also offers Set Desired Focus Widget on UserWidget: it can name
a child that should receive focus when the root receives it. That setter
returns false if the supplied Widget is not a child of that User Widget.
3. The active path must allow focus¶
The target must be in the active hierarchy and effectively visible/enabled. A Hidden or Collapsed target has no usable visible focus path. A disabled target, or a target under a disabled ancestor, cannot serve as a normal interactive focus stop.
Pointer hit-test visibility is related but different. Hit Test Invisible
controls pointer discovery; it is not a substitute for enabled state or a
complete keyboard-focus policy. Likewise, Render Opacity 0 can make a
focused control visually disappear without making it Hidden.
4. Input must be routed to UI¶
Focus can be set correctly while gameplay input mode still owns the keys.
Opening an interactive menu normally pairs focus with Set Input Mode UI Only
or Set Input Mode Game and UI, plus cursor and pause policy. A focus setter
does not change any of those settings.
What Set Is Enabled actually changes¶
Set Is Enabled writes one widget's enabled flag. The Blueprint node has an
execution output and no Boolean return; the C++ call shape is
void UWidget::SetIsEnabled(bool).
Disabled means the widget is unavailable for normal user interaction. It does not mean absent:
| Property while disabled | Typical result |
|---|---|
| Paint | still painted |
| Layout | still occupies its normal space |
| Pointer/keyboard interaction | blocked as an enabled control |
| Disabled visual | often supplied by the control/style |
| UObject variables/functions | still exist and can be changed by code |
| Animations/timers/update logic | not automatically stopped |
| Parent/viewport relationship | unchanged |
That makes disabled state useful for a visible unavailable action:
CraftButton.SetIsEnabled(CanAffordRecipe)
CraftRequirementText.SetText(reason when false)
Do not use a disabled style as the only explanation. Show why an important action is unavailable, especially when color alone would be ambiguous.
Disabled state composes through parents¶
An ancestor gates its descendants:
MainMenuPanel = disabled
|-- ResumeButton = enabled
`-- SettingsButton = enabled
effective result: both buttons are disabled
The child flags can remain true; re-enabling the parent allows each child to
resume according to its own stored flag. Setting one child enabled while its
ancestor remains disabled cannot override the ancestor.
This matters for modal dialogs. If the confirmation dialog is nested under the panel you disable, the dialog is disabled too. Put the modal in a sibling overlay/layer above the disabled background panel:
MenuRoot Overlay
|-- MainMenuPanel <- disable while modal is open
`-- ConfirmDialog <- separate sibling, stays enabled
Disabled style is presentation, not proof¶
Standard controls commonly draw a disabled appearance, but style choice can make enabled and disabled states look identical. Conversely, dimming a Widget with Render Opacity does not disable it.
When a button looks disabled but still clicks, inspect Get Is Enabled on the
exact instance and its ancestors. When it is disabled but looks normal, inspect
the Button style or add a deliberate state treatment; do not reimplement the
interaction gate with a second Boolean click check unless gameplay eligibility
also needs validation at the action boundary.
How focus moves after the first setter¶
Calling a setter establishes the current focus target; it does not lock focus there forever.
- Keyboard/gamepad navigation moves from the current target according to UMG navigation rules and the available visible, enabled, focusable widgets.
- Mouse/pointer interaction can move focus when the clicked control's behavior accepts focus. Not every visible control does.
- Opening a new window/menu/modal can replace the focus path.
- Code can call another focus setter later in the frame.
- Hiding, disabling, or removing a target makes it unsuitable, but does not express which remaining control your design wants next.
UMG can infer simple directional navigation from layout. Dense grids,
wrap-around rows, inventory screens, and modal boundaries often need explicit
navigation rules. Set Navigation Rule Explicit can name the next widget for
a direction, but only for widgets already in a widget tree.
A missing focus outline is not proof that focus failed. Project
Render Focus Rule can show the focus brush always, only for non-pointer or
navigation focus, or never. Check Has User Focus with the intended Player
Controller or Has Keyboard Focus before diagnosing only from the artwork.
Restore focus deliberately¶
The safe pattern chooses a stable destination for every transition.
Open a menu¶
Create/store MenuWidget with Owning Player = LocalPC
-> Add to Player Screen
-> MenuRoot Set Visibility Visible
-> MenuRoot Set Is Enabled true
-> Set Input Mode UI Only(LocalPC, Widget to Focus = FirstButton)
-> FirstButton Set User Focus(LocalPC)
-> LocalPC Show Mouse Cursor true
The input-mode node can set a focus target itself; the explicit final setter is useful when a later visibility/activation step determines the real first control. Choose one ordered open function so two systems do not fight.
Open and close a confirmation modal¶
OpenConfirm:
remember ReturnFocusWidget = DeleteButton
MainPanel Set Is Enabled false
ConfirmPanel Set Visibility Visible
ConfirmPanel Set Is Enabled true
ConfirmYesButton Set User Focus(LocalPC)
CloseConfirm:
ConfirmPanel Set Visibility Collapsed
MainPanel Set Is Enabled true
if ReturnFocusWidget is valid, visible, enabled, and focusable:
ReturnFocusWidget Set User Focus(LocalPC)
else:
FirstMainMenuButton Set User Focus(LocalPC)
Store a reference to a known return control, not a promise that "whatever had focus" will still exist. List entries can be regenerated, buttons can become disabled, and a screen transition can destroy the old Widget instance.
Disable the currently focused action¶
Before disabling a focused Button, choose the next eligible Button and move focus to it. Re-enabling the old Button later does not communicate that it should steal focus back.
if PurchaseButton HasUserFocus(LocalPC):
BackButton Set User Focus(LocalPC)
PurchaseButton Set Is Enabled false
Close the menu into gameplay¶
MenuRoot Remove from Parent (or hide it)
-> Set Input Mode Game Only(LocalPC)
-> LocalPC Show Mouse Cursor false
-> restore any movement/look gates or mapping contexts changed on open
If another menu replaces it, add/show/enable the new menu and focus its first control for the same user. Do not focus a Widget and then immediately remove its root from the hierarchy.
Split-screen and network boundary¶
Each local player needs a coherent bundle:
- its own local Player Controller;
- its own User Widget instance with that controller as Owning Player;
Add to Player Screenfor that player's screen region;- input mode/cursor policy applied to that controller; and
- Set Focus/Set User Focus for that same user.
One player's menu should not disable or focus the other player's controls unless the game deliberately implements a shared pause/modal policy.
Screen UI and focus are local cosmetic/input state. They are not replicated. The server may replicate "this purchase is unavailable" or "the match is paused," but each client updates enabled state and focus on its own widget instances. A dedicated server has no local viewport focus target.
When it fails (and what failure does)¶
None of these setters returns a success flag or throws a gameplay exception. Common failures are:
- Target is
None. Blueprint can reportAccessed None; no intended focus or enabled state changes. - The widget is not constructed or present. The UObject exists, but there is no active Slate path to focus.
- The target does not support focus. A decorative/root container was targeted instead of a Button or focusable User Widget.
- An ancestor hides or disables it. The child's own settings look right, but the effective path is unavailable.
- The Player Controller is
None, remote, or the wrong local player. Set User Focus cannot select the intended Slate user. - Another step immediately moves focus. Input-mode setup, a second open function, navigation, a pointer click, or another setter wins later.
- The wrong widget instance was targeted. A regenerated ListView entry or duplicate menu is visible while an old stored reference receives the call.
- The focus is real but the brush is hidden. Render Focus Rule or style makes diagnosis by appearance misleading.
- The control is enabled but pointer clicks still fail. Visibility, hit-test visibility, Z order, input mode, or another overlay blocks it.
- The control was re-enabled but focus never returned. Enabled state does not encode focus-restoration policy.
Use Supports Keyboard Focus, Has User Focus, Has User Focused
Descendants, Get Is Enabled, Get Visibility, and Get Owning Player on
the exact runtime instance. Then inspect the path and effective state in Widget
Reflector. A Delay can hide construction/order mistakes temporarily; it does
not identify the wrong user, ancestor, or instance.
The C++ shape¶
The C++ equivalents return void, so validate the references and policy before
the call:
void USettingsMenu::FocusFirstOption(
APlayerController* LocalController,
UWidget* FirstOption)
{
if (!IsValid(LocalController) || !IsValid(FirstOption))
{
return;
}
FirstOption->SetIsEnabled(true);
FirstOption->SetUserFocus(LocalController);
}
For a control inside the correctly owned User Widget, FirstOption->SetFocus()
is the owning-user convenience. SetKeyboardFocus() is the no-controller
keyboard route.
What these nodes do not do¶
They do not:
- create, add, show, hide, remove, or destroy a Widget;
- make an inherently non-focusable widget support focus;
- focus every local user when Set Keyboard Focus is called;
- turn a remote/server Player Controller into a local Slate user;
- set the Player Controller's Game/UI input mode;
- show or hide the mouse cursor;
- pause gameplay or block pawn movement/look by themselves;
- guarantee a visible focus brush;
- configure directional navigation or wrap-around policy;
- make disabled state remove layout space or hide the widget;
- stop code, animations, timers, bindings, or dispatcher calls on a disabled Widget;
- choose a replacement when the focused Widget disappears; or
- replicate focus/enabled state to another machine.
Lookalikes - which one do I want?¶
| Node / property | Use when | Watch out |
|---|---|---|
| Set Focus | A widget should receive focus for its owning user. | Correct Owning Player context is the foundation. |
| Set User Focus | Code must name the specific local Player Controller/user. | A remote or wrong controller cannot focus the intended local UI. |
| Set Keyboard Focus | The application's keyboard focus target is unambiguous. | No Player Controller pin; not an all-users operation. |
| Set Desired Focus Widget | A User Widget should forward root focus to a known child. | Returns false when the target is not its child. |
| Set Input Mode UI Only / Game and UI | The controller must route incoming input toward UI. | Display, enabled state, cursor, and pause remain separate. |
| Navigation Rules | D-pad/arrow movement needs explicit next/stop/wrap behavior. | Rules act from an existing focus target in the live tree. |
| Set Is Enabled | A visible control/subtree should be unavailable for interaction. | Ancestors gate descendants; layout remains. |
| Set Visibility | Painting, layout participation, or pointer hit testing should change. | It does not define focus recovery or enabled style. |
| Hit Test Invisible | A visible decoration should not receive pointer hits. | Pointer policy is not the same as keyboard focus or enabled state. |
| Remove from Parent | The Widget should detach from its panel or viewport. | Restore focus/input mode before relying on gameplay controls. |
Rule of thumb: identify the local user, make one real control present and eligible, focus it after activation, and name the destination for every disable/hide/remove transition.
Going deeper¶
- Set Input Mode & Show Mouse Cursor - the separate controller-level input-routing and cursor bundle.
- Create Widget + Add to Viewport - owning
player,
Add to Player Screen, and keeping the correct runtime instance. - Set Visibility: Hidden, Collapsed, and hit testing - painting, layout, pointer policy, and ancestor composition.
- Remove from Parent and widget lifetime - focus/input restoration, stored references, and cleanup when a menu closes.
- Buttons, Progress Bars, and basic UMG events - Button events, normalized bars, and UI-to-gameplay communication.
- Official docs: UWidget, Set Focus, Supports Keyboard Focus, Set Desired Focus Widget, Set Navigation Rule Explicit, and Render Focus Rule.
- Engine source (requires engine access - we do not reproduce it here):
UWidget::SetFocus,SetKeyboardFocus,SetUserFocus, andSetIsEnabledinEngine/Source/Runtime/UMG/Private/Components/Widget.cpp; their declarations and owning-player queries inEngine/Source/Runtime/UMG/Public/Components/Widget.h; and Slate focus-path behavior inFSlateApplication::SetKeyboardFocusandSetUserFocusunderEngine/Source/Runtime/Slate/Private/Framework/Application/SlateApplication.cpp.