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:

PropertyEffect while the widget is active
InputConfig = MenuUI captures input; the game receives none.
InputConfig = GameGame keeps input; UI actions (Back, Escape) still route.
InputConfig = GameAndMenuUI gets first chance; unhandled input falls through to the game.
InputConfig = DefaultNo opinion - the config of the widget below (or the action domain) stays.
GameMouseCaptureMode / MenuMouseCaptureModeHow the viewport captures the mouse in the respective mode (default CapturePermanently / NoCapture).
bIgnoreMoveInput / bIgnoreLookInputAdditionally freeze pawn move/look via the player controller while active.
bRestoreInputTypeOnDeactivatePut 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.