More fixing everything

This commit is contained in:
2026-04-22 07:22:55 -04:00
parent 4420c52b74
commit d985a6bc55
3 changed files with 47 additions and 41 deletions

View File

@@ -164,7 +164,7 @@ void AlxPlayerControllerBase::AddWidgetToRoot(UUserWidget *Widget)
if (Widget->GetParent() == PC->RootCanvas) return; if (Widget->GetParent() == PC->RootCanvas) return;
UlxRootCanvasSlot *Slot = PC->RootCanvas->AddChildToRootCanvas(Widget); UlxRootCanvasSlot *Slot = PC->RootCanvas->AddChildToRootCanvas(Widget);
Slot->SetZOrder(0); Slot->SlotUnderConstruction = false;
} }
void AlxPlayerControllerBase::BuildInputStack(TArray<UInputComponent*>& InputStack) void AlxPlayerControllerBase::BuildInputStack(TArray<UInputComponent*>& InputStack)
@@ -256,10 +256,6 @@ void AlxPlayerControllerBase::BuildInputStack(TArray<UInputComponent*>& InputSta
void AlxPlayerControllerBase::UpdateInputMode() void AlxPlayerControllerBase::UpdateInputMode()
{ {
// Drain any deferred ZOrder writes from SetWidgetWindowManagement
// before we read the front-most slot.
RootCanvas->PropagateZOrderToSlate();
// Get all the various objects we need to be able to manipulate // Get all the various objects we need to be able to manipulate
// the input mode. // the input mode.
UGameViewportClient *GameViewportClient = GetWorld()->GetGameViewport(); UGameViewportClient *GameViewportClient = GetWorld()->GetGameViewport();

View File

@@ -18,6 +18,34 @@ UlxRootCanvasSlot::UlxRootCanvasSlot(const FObjectInitializer& ObjectInitializer
SetOffsets(FMargin(0.0f, 0.0f, 0.0f, 0.0f)); SetOffsets(FMargin(0.0f, 0.0f, 0.0f, 0.0f));
} }
void UlxRootCanvasSlot::SetZOrderReliable(int32 Order)
{
if (SlotUnderConstruction)
{
PRAGMA_DISABLE_DEPRECATION_WARNINGS
ZOrder = Order;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
}
else
{
SetZOrder(Order);
}
}
int32 UlxRootCanvasSlot::GetZOrderReliable()
{
if (SlotUnderConstruction)
{
PRAGMA_DISABLE_DEPRECATION_WARNINGS
return ZOrder;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
}
else
{
return GetZOrder();
}
}
UClass* UlxRootCanvasPanel::GetSlotClass() const UClass* UlxRootCanvasPanel::GetSlotClass() const
{ {
return UlxRootCanvasSlot::StaticClass(); return UlxRootCanvasSlot::StaticClass();
@@ -49,23 +77,11 @@ int32 UlxRootCanvasPanel::GetMaxZOrder() const
{ {
UlxRootCanvasSlot *TypedSlot = Cast<UlxRootCanvasSlot>(PanelSlot); UlxRootCanvasSlot *TypedSlot = Cast<UlxRootCanvasSlot>(PanelSlot);
check(TypedSlot); check(TypedSlot);
MaxZOrder = FMath::Max(MaxZOrder, TypedSlot->GetZOrder()); MaxZOrder = FMath::Max(MaxZOrder, TypedSlot->GetZOrderReliable());
} }
return MaxZOrder; return MaxZOrder;
} }
void UlxRootCanvasPanel::PropagateZOrderToSlate()
{
if (!MustPropagateZOrderToSlate) return;
MustPropagateZOrderToSlate = false;
for (UPanelSlot *PanelSlot : Slots)
{
UlxRootCanvasSlot *TypedSlot = Cast<UlxRootCanvasSlot>(PanelSlot);
check(TypedSlot);
TypedSlot->SetZOrder(TypedSlot->GetZOrder());
}
}
TArray<UlxRootCanvasSlot*> UlxRootCanvasPanel::GetSortedUserWidgets() TArray<UlxRootCanvasSlot*> UlxRootCanvasPanel::GetSortedUserWidgets()
{ {
TArray<UlxRootCanvasSlot*> Result; TArray<UlxRootCanvasSlot*> Result;
@@ -105,17 +121,6 @@ void UlxRootCanvasPanel::SetWidgetWindowManagement(class UUserWidget *Widget,
Slot->BlockInput = BlockInput; Slot->BlockInput = BlockInput;
Slot->EnableEnhancedInput = EnableEnhancedInput; Slot->EnableEnhancedInput = EnableEnhancedInput;
Widget->SetDesiredFocusWidget(DesiredFocusWidget); Widget->SetDesiredFocusWidget(DesiredFocusWidget);
if (BringToFront) if (BringToFront) Slot->SetZOrderReliable(Panel->GetMaxZOrder() + 1);
{
// Write the int32 ZOrder UPROPERTY directly and defer the
// Slate-side push to PropagateZOrderToSlate. Going through SetZOrder
// here is unsafe when called from Event Construct: the FSlot
// has been Exposed but its Owner isn't set yet, which fires
// an ensure in SConstraintCanvas::FSlot::SetZOrder.
PRAGMA_DISABLE_DEPRECATION_WARNINGS
Slot->ZOrder = Panel->GetMaxZOrder() + 1;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
Panel->MustPropagateZOrderToSlate = true;
}
} }

View File

@@ -59,6 +59,22 @@ public:
// events in the Event Graph are deactivated. // events in the Event Graph are deactivated.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Input Mode") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Input Mode")
bool EnableEnhancedInput = true; bool EnableEnhancedInput = true;
// Knowing whether the slot is under construction helps us to work
// around some bugs in Unreal. See below.
bool SlotUnderConstruction = true;
// Reliable version of SetZOrder. There is a bug in the normal version of
// SetZOrder: it crashes if you use it during OnConstruct. We have a
// workaround, but it requires using a different getter and setter.
UFUNCTION(BlueprintCallable, Category = "Luprex|Input Mode")
void SetZOrderReliable(int32 Order);
// Reliable version of GetZOrder. There is a bug in the normal version of
// SetZOrder: it crashes if you use it during OnConstruct. We have a
// workaround, but it requires using a different getter and setter.
UFUNCTION(BlueprintCallable, Category = "Luprex|Input Mode")
int32 GetZOrderReliable();
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@@ -91,13 +107,6 @@ public:
// Used as the basis for placing new widgets on top. // Used as the basis for placing new widgets on top.
int32 GetMaxZOrder() const; int32 GetMaxZOrder() const;
// SetZOrder is buggy: if you call it inside Event Construct,
// it crashes. So we've developed a hack to make it reliable.
// To set the zorder, you store the value in the slot property,
// without calling SetZorder. This routine, which is used later,
// propagates that value into the slate widgets.
void PropagateZOrderToSlate();
// This function updates several window-management-related properties // This function updates several window-management-related properties
// which are stored in the UserWidget and the lxRootCanvasSlot. Note that // which are stored in the UserWidget and the lxRootCanvasSlot. Note that
// it is perfectly legal to edit these properties by other means: this // it is perfectly legal to edit these properties by other means: this
@@ -122,10 +131,6 @@ protected:
// UPanelWidget // UPanelWidget
virtual UClass* GetSlotClass() const override; virtual UClass* GetSlotClass() const override;
public:
bool MustPropagateZOrderToSlate = false;
}; };