Concept: Input Routing & Activatable Widgets
CommonUI decides, per frame, whether input goes to the game, the UI, or both - based on the active activatable widgets. UCrimsonActivatableWidget packages that decision into per-widget defaults so designers configure input routing where they build the screen, not in scattered controller code.
What happens on activation
When a Crimson activatable widget activates, its GetDesiredInputConfig override translates the widget's settings into CommonUI's FUIInputConfig:
| Property | Effect while the widget is active |
|---|---|
InputConfig = Menu | UI captures input; the game receives none. |
InputConfig = Game | Game keeps input; UI actions (Back, Escape) still route. |
InputConfig = GameAndMenu | UI gets first chance; unhandled input falls through to the game. |
InputConfig = Default | No opinion - the config of the widget below (or the action domain) stays. |
GameMouseCaptureMode / MenuMouseCaptureMode | How the viewport captures the mouse in the respective mode (default CapturePermanently / NoCapture). |
bIgnoreMoveInput / bIgnoreLookInput | Additionally freeze pawn move/look via the player controller while active. |
bRestoreInputTypeOnDeactivate | Put the previous input config back when this widget deactivates. |
The InputMode tag baseline
With bForceInputModeTagsOnActivate enabled, the widget stamps the matching visibility tag - InputMode.Game and/or InputMode.Menu - onto CommonUI's visibility system one tick after activation. This exists because CommonUI only broadcasts input-mode changes: the very first widget to care about input-mode tags would otherwise see an empty baseline until the mode changes once. Widgets that gate their own visibility or bindings on InputMode.* tags (input-mode-filtered bindings, HUD elements that hide in menus) rely on this being on for the persistent HUD layout - UCrimsonHUDLayout enables it in its constructor.
Action domains (5.8 Enhanced Input path)
With bEnableEnhancedInputSupport=True you can go further and give every layer a default input mode via a UCommonInputActionDomainTable (ActionDomainTable in CommonInputSettings): one UCommonInputActionDomain per layer (Game = Game mode, Menu/Modal = Menu mode). Widgets then inherit their layer's mode and InputConfig becomes a per-widget override rather than a requirement. This is optional - the per-widget InputConfig works fine without domains.
Where the escape action fits
UI actions (Click, Back, Escape, your own) are routed by CommonUI's action router, not by pawn input. UCrimsonHUDLayout binds Escape with InputMode = Game so it fires during gameplay; a menu with InputConfig = Menu then owns input until it deactivates. The Back action (Quick Start step 4) is what lets gamepads dismiss activatable widgets with no extra wiring.
Multiplayer note
All of this is owning-client-local: input configs, tags, and action routing never replicate. Server code must not assume anything about a client's input mode; gameplay consequences (pausing, ability use) travel through normal replication and RPCs with server validation.