Lots of work on input processing

This commit is contained in:
2026-04-18 01:11:21 -04:00
parent 6388de9b39
commit fd970f20c3
4 changed files with 17 additions and 13 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -94,8 +94,7 @@ void FlxInputModeRequests::GarbageCollect()
int32 N = Requests.Num(); int32 N = Requests.Num();
Requests.RemoveAll([](const FlxInputModeRequest &Entry) Requests.RemoveAll([](const FlxInputModeRequest &Entry)
{ {
UUserWidget *W = Entry.Widget; return !IsValid(Entry.Widget);
return W == nullptr || !IsValid(W) || W->GetParent() == nullptr;
}); });
if (Requests.Num() < N) Dirty = true; if (Requests.Num() < N) Dirty = true;
} }

View File

@@ -197,7 +197,9 @@ void AlxPlayerControllerBase::BuildInputStack(TArray<UInputComponent*>& InputSta
const TArray<FlxInputModeRequest> &Requests = InputModeRequests.GetRequests(); const TArray<FlxInputModeRequest> &Requests = InputModeRequests.GetRequests();
for (int32 Idx = Requests.Num() - 1; Idx >= 0; --Idx) for (int32 Idx = Requests.Num() - 1; Idx >= 0; --Idx)
{ {
if (UInputComponent *IC = GetWidgetInputComponent(Requests[Idx].Widget)) UUserWidget *Widget = Requests[Idx].Widget;
if (!Widget->IsInViewport()) continue;
if (UInputComponent *IC = GetWidgetInputComponent(Widget))
{ {
IC->bBlockInput = Requests[Idx].BlockInput; IC->bBlockInput = Requests[Idx].BlockInput;
InputStack.Push(IC); InputStack.Push(IC);
@@ -219,16 +221,19 @@ void AlxPlayerControllerBase::UpdateInputMode()
TSharedRef<SViewport> ViewportWidgetRef = ViewportWidget.ToSharedRef(); TSharedRef<SViewport> ViewportWidgetRef = ViewportWidget.ToSharedRef();
FReply &SlateOperations = LocalPlayer->GetSlateOperations(); FReply &SlateOperations = LocalPlayer->GetSlateOperations();
// The first entry in InputModeRequests (highest priority) dictates the // The first active entry in InputModeRequests dictates the
// pointer / capture / focus state. If there are no requests at all, // pointer / capture / focus state. If there are no requests at all,
// fall back to a static default-constructed request. // fall back to a static default-constructed request.
static const FlxInputModeRequest EmptyRequest; static const FlxInputModeRequest EmptyRequest;
const TArray<FlxInputModeRequest> &Requests = InputModeRequests.GetRequests(); const FlxInputModeRequest *Top = &EmptyRequest;
const FlxInputModeRequest &Top = Requests.IsEmpty() ? EmptyRequest : Requests[0]; for (const FlxInputModeRequest &Req : InputModeRequests.GetRequests())
{
if (Req.Widget->IsInViewport()) { Top = &Req; break; }
}
SetShowMouseCursor(Top.ShowPointer); SetShowMouseCursor(Top->ShowPointer);
if (Top.ShowPointer) if (Top->ShowPointer)
{ {
// Pointer-visible mode: full macroexpansion of SetInputModeGameAndUI // Pointer-visible mode: full macroexpansion of SetInputModeGameAndUI
// — the BP wrapper, APlayerController::SetInputMode, and // — the BP wrapper, APlayerController::SetInputMode, and
@@ -254,7 +259,7 @@ void AlxPlayerControllerBase::UpdateInputMode()
// UWidget holds its live SWidget in a cached TSharedPtr; we need a // UWidget holds its live SWidget in a cached TSharedPtr; we need a
// TSharedRef for SetUserFocus. Fall back to the viewport if the // TSharedRef for SetUserFocus. Fall back to the viewport if the
// target has never been constructed (cached widget is null). // target has never been constructed (cached widget is null).
TSharedPtr<SWidget> SlateFocus = Top.Focus ? Top.Focus->GetCachedWidget() : nullptr; TSharedPtr<SWidget> SlateFocus = Top->Focus ? Top->Focus->GetCachedWidget() : nullptr;
if (SlateFocus.IsValid()) if (SlateFocus.IsValid())
{ {
SlateOperations.SetUserFocus(SlateFocus.ToSharedRef()); SlateOperations.SetUserFocus(SlateFocus.ToSharedRef());