In this lesson, you will learn how to configure input propagation and focus traversal rules to ensure your custom widgets reliably intercept and process user interactions.
Understanding Input Routing
When a user clicks or presses a key, Slate doesn't just "know" which widget to trigger. It follows an Input Routing process, traversing the widget hierarchy from the top-most visual layer down to the underlying elements. If a widget’s OnMouseButtonDown function returns FReply::Unhandled(), the input continues to propagate to the parent or widgets behind it. To "capture" the input, you must return FReply::Handled(), which stops the event from bubbling further.
Managing Focus Traversal
Focus is the primary mechanism for keyboard and gamepad navigation. When a widget has focus, it becomes the target for all non-mouse inputs. You manage this using the bIsFocusable property and the GetNavigationAction override.
If you are building a custom UI panel, you should define how focus moves when the user presses a directional key. You can explicitly set navigation rules in your widget’s construct or via the FNavigationReply struct.
For example, to ensure your custom widget captures focus on click, your OnMouseButtonDown should look like this:
FReply SMyCustomWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
// Capture focus so keyboard navigation works
return FReply::Handled().SetUserFocus(SharedThis(this), EFocusCause::Mouse);
}
Designing for Interaction
When designing custom widgets, always consider the Visibility setting. A widget with Visibility::HitTestInvisible will be rendered but effectively ignored by the input routing system, allowing clicks to pass through to widgets beneath it. Conversely, Visibility::Visible acts as a wall that consumes input. By strategically toggling these settings and returning the correct FReply state, you create a responsive UI that prevents "input bleed," where a button click accidentally triggers gameplay actions instead of a menu selection.
Key Takeaway: Precise input control requires returning the appropriate FReply state to stop event propagation and explicitly setting focus to ensure your widgets remain the intended target for navigation inputs.