From 30ecbefd1050d0c83835cca9c62c44e65d356cad Mon Sep 17 00:00:00 2001 From: Arnaud Jamin Date: Thu, 13 Feb 2025 00:51:44 -0500 Subject: [PATCH] Retake the focus when loosing it while ImGui has the input --- .../Private/CogEngineWindow_Slate.cpp | 2 +- .../CogImgui/Private/CogImguiContext.cpp | 31 +++++++++++++++---- .../CogImgui/Private/CogImguiWidget.cpp | 11 +++++++ .../Source/CogImgui/Public/CogImguiContext.h | 6 +++- .../Source/CogImgui/Public/CogImguiWidget.h | 2 ++ 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Slate.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Slate.cpp index ab63d64..63d45b9 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Slate.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Slate.cpp @@ -52,7 +52,7 @@ void FCogEngineWindow_Slate::RenderContent() void FCogEngineWindow_Slate::RenderUser(FSlateUser& User) { - if (ImGui::BeginTable("SlateUser", 2, ImGuiTableFlags_Borders)) + if (ImGui::BeginTable("SlateUser", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable)) { constexpr ImVec4 LabelColor(1.0f, 1.0f, 1.0f, 0.5f); diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiContext.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiContext.cpp index 8610c3d..8a428f0 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiContext.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiContext.cpp @@ -206,6 +206,17 @@ void FCogImguiContext::Shutdown() } } +//-------------------------------------------------------------------------------------------------------------------------- +void FCogImguiContext::OnImGuiWidgetFocusLost() +{ + FCogImGuiContextScope ImGuiContextScope(Context, PlotContext); + + if (bEnableInput && GameViewport->GetGameViewportWidget()->HasUserFocus(0)) + { + bRetakeFocus = true; + } +} + //-------------------------------------------------------------------------------------------------------------------------- void FCogImguiContext::OnDisplayMetricsChanged(const FDisplayMetrics& DisplayMetrics) const { @@ -238,7 +249,7 @@ void FCogImguiContext::OnDisplayMetricsChanged(const FDisplayMetrics& DisplayMet bool FCogImguiContext::BeginFrame(float InDeltaTime) { FCogImGuiContextScope ImGuiContextScope(Context, PlotContext); - + //------------------------------------------------------------------------------------------------------- // Skip the first frame, to let the main widget update its TickSpaceGeometry which is returned by the // platform callback ImGui_GetWindowPos. When using viewports Imgui needs to know the main viewport @@ -250,6 +261,16 @@ bool FCogImguiContext::BeginFrame(float InDeltaTime) return false; } + //------------------------------------------------------------------------------------------------------- + // Sometime the game can retake unaware that ImGui want to keep the focus and mouse unlock. + // This typically happens when switching level. + //------------------------------------------------------------------------------------------------------- + if (bRetakeFocus) + { + SetEnableInput(true); + bRetakeFocus = false; + } + ImGuiIO& IO = ImGui::GetIO(); IO.DeltaTime = InDeltaTime; @@ -696,16 +717,14 @@ static APlayerController* GetLocalPlayerController(const UWorld* World) } //-------------------------------------------------------------------------------------------------------------------------- -void FCogImguiContext::SetEnableInput(bool Value) +void FCogImguiContext::SetEnableInput(const bool InValue) { FCogImGuiContextScope ImGuiContextScope(Context, PlotContext); - bEnableInput = Value; + bEnableInput = InValue; if (FSlateApplication::IsInitialized() == false) - { - return; - } + { return; } if (bEnableInput) { diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp index 1a0584c..8ad7315 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp @@ -277,6 +277,17 @@ FReply SCogImguiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocu return Super::OnFocusReceived(MyGeometry, FocusEvent); } +//-------------------------------------------------------------------------------------------------------------------------- +void SCogImguiWidget::OnFocusLost(const FFocusEvent& InFocusEvent) +{ + SLeafWidget::OnFocusLost(InFocusEvent); + + if (Context != nullptr) + { + Context->OnImGuiWidgetFocusLost(); + } +} + //-------------------------------------------------------------------------------------------------------------------------- void SCogImguiWidget::RefreshVisibility() { diff --git a/Plugins/Cog/Source/CogImgui/Public/CogImguiContext.h b/Plugins/Cog/Source/CogImgui/Public/CogImguiContext.h index a9dccac..8c47e6e 100644 --- a/Plugins/Cog/Source/CogImgui/Public/CogImguiContext.h +++ b/Plugins/Cog/Source/CogImgui/Public/CogImguiContext.h @@ -47,7 +47,7 @@ public: bool GetEnableInput() const { return bEnableInput; } - void SetEnableInput(bool Value); + void SetEnableInput(bool InValue); bool GetWantCaptureMouse() const { return bWantCaptureMouse; } @@ -81,6 +81,8 @@ public: TSharedPtr GetMainWidget() const { return MainWidget; } + void OnImGuiWidgetFocusLost(); + static bool GetIsNetImguiInitialized() { return bIsNetImGuiInitialized; } private: @@ -179,6 +181,8 @@ private: bool bSkipRendering = false; + bool bRetakeFocus = false; + static bool bIsNetImGuiInitialized; }; diff --git a/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h b/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h index 54347d2..cbca3bb 100644 --- a/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h +++ b/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h @@ -51,6 +51,8 @@ public: virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent) override; + + virtual void OnFocusLost(const FFocusEvent& InFocusEvent) override; void SetDrawData(const ImDrawData* InDrawData);