Hi, Unreal Engine Support.
When I use a RetainerBox to package a CanvasPanel or a Widget, I found that the child widget in RetainerBox draw incorret SelectionOuline ,if not in full screen mode, it more obvious. UE4 engine version is 4.23.
After reading the UE4 4.23 source code,
SDesignerView.cpp →
DrawSelectionAndHoverOutline →
FDesignTimeUtils::GetArrangedWidgetRelativeToWindow
line 32 in FDesignTimeUtils.cpp FSlateApplication::Get().FindWidgetWindow(Widget)
do not find correct CurrentWindowRef.
Because SRetainerWidget new a SVirtualWindow in Construct, the function FSlateApplication::Get().FindWidgetWindow(Widget) should return the editor window, but if widget is type of SRetainerWidget, it return the SVirtualWindow in SRetainerWidget. Here is the bug happened.
So I add a bug fix bug this code in function FDesignTimeUtils::GetArrangedWidgetRelativeToWindow, the bug fix.
bool FDesignTimeUtils::GetArrangedWidgetRelativeToWindow(TSharedRef<SWidget> Widget, FArrangedWidget& ArrangedWidget)
{
TSharedPtr<SWindow> WidgetWindow = FSlateApplication::Get().FindWidgetWindow(Widget);
if ( !WidgetWindow.IsValid() )
{
return false;
}
// fix RetainerBox find window incorrect
while(WidgetWindow->GetParentWidget().IsValid())
{
TSharedRef<SWidget> CurrentWidget = WidgetWindow->GetParentWidget().ToSharedRef();
TSharedPtr<SWindow> ParentWidgetWindow = FSlateApplication::Get().FindWidgetWindow(CurrentWidget);
if(ParentWidgetWindow.IsValid())
{
WidgetWindow = ParentWidgetWindow;
}
else
{
break;
}
}
// end fix RetainerBox find window incorrect
TSharedRef<SWindow> CurrentWindowRef = WidgetWindow.ToSharedRef();
FWidgetPath WidgetPath;
if ( FSlateApplication::Get().GeneratePathToWidgetUnchecked(Widget, WidgetPath) )
{
ArrangedWidget = WidgetPath.FindArrangedWidget(Widget).Get(FArrangedWidget::GetNullWidget());
ArrangedWidget.Geometry.AppendTransform(FSlateLayoutTransform(Inverse(CurrentWindowRef->GetPositionInScreen())));
//ArrangedWidget.Geometry.AppendTransform(Inverse(CurrentWindowRef->GetLocalToScreenTransform()));
return true;
}
return false;
}