From 1f06006cc03c1fcb21423d3ccdcc71a613b3b7d0 Mon Sep 17 00:00:00 2001 From: srkizer Date: Thu, 7 Aug 2025 11:18:40 +0900 Subject: [PATCH] Fix combobox callback impl (#2347) * Fix combobox callback impl * Make ImGuiBackend delegates public * Release ImGui focus when the game window loses focus --- .../Delegates/ImGuiBuildUiDelegate.cs | 4 ++++ .../Delegates/ImGuiNewInputFrameDelegate.cs | 4 ++++ .../Delegates/ImGuiNewRenderFrameDelegate.cs | 4 ++++ .../ImGuiBackend/Dx11Win32Backend.cs | 7 +++--- .../Interface/ImGuiBackend/IImGuiBackend.cs | 22 ++++++------------- .../InputHandler/Win32InputHandler.cs | 8 +++++++ .../Interface/Internal/InterfaceManager.cs | 3 ++- .../Custom/ImGui.ComboAndList.cs | 6 ++--- 8 files changed, 36 insertions(+), 22 deletions(-) create mode 100644 Dalamud/Interface/ImGuiBackend/Delegates/ImGuiBuildUiDelegate.cs create mode 100644 Dalamud/Interface/ImGuiBackend/Delegates/ImGuiNewInputFrameDelegate.cs create mode 100644 Dalamud/Interface/ImGuiBackend/Delegates/ImGuiNewRenderFrameDelegate.cs diff --git a/Dalamud/Interface/ImGuiBackend/Delegates/ImGuiBuildUiDelegate.cs b/Dalamud/Interface/ImGuiBackend/Delegates/ImGuiBuildUiDelegate.cs new file mode 100644 index 000000000..6ebab55c6 --- /dev/null +++ b/Dalamud/Interface/ImGuiBackend/Delegates/ImGuiBuildUiDelegate.cs @@ -0,0 +1,4 @@ +namespace Dalamud.Interface.ImGuiBackend.Delegates; + +/// Delegate to be called when ImGui should be used to layout now. +public delegate void ImGuiBuildUiDelegate(); diff --git a/Dalamud/Interface/ImGuiBackend/Delegates/ImGuiNewInputFrameDelegate.cs b/Dalamud/Interface/ImGuiBackend/Delegates/ImGuiNewInputFrameDelegate.cs new file mode 100644 index 000000000..7397d8d7f --- /dev/null +++ b/Dalamud/Interface/ImGuiBackend/Delegates/ImGuiNewInputFrameDelegate.cs @@ -0,0 +1,4 @@ +namespace Dalamud.Interface.ImGuiBackend.Delegates; + +/// Delegate to be called on new input frame. +public delegate void ImGuiNewInputFrameDelegate(); diff --git a/Dalamud/Interface/ImGuiBackend/Delegates/ImGuiNewRenderFrameDelegate.cs b/Dalamud/Interface/ImGuiBackend/Delegates/ImGuiNewRenderFrameDelegate.cs new file mode 100644 index 000000000..4a4b38b71 --- /dev/null +++ b/Dalamud/Interface/ImGuiBackend/Delegates/ImGuiNewRenderFrameDelegate.cs @@ -0,0 +1,4 @@ +namespace Dalamud.Interface.ImGuiBackend.Delegates; + +/// Delegate to be called on new render frame. +public delegate void ImGuiNewRenderFrameDelegate(); diff --git a/Dalamud/Interface/ImGuiBackend/Dx11Win32Backend.cs b/Dalamud/Interface/ImGuiBackend/Dx11Win32Backend.cs index ebb8e67e2..ea609828d 100644 --- a/Dalamud/Interface/ImGuiBackend/Dx11Win32Backend.cs +++ b/Dalamud/Interface/ImGuiBackend/Dx11Win32Backend.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using Dalamud.Bindings.ImGui; using Dalamud.Bindings.ImGuizmo; using Dalamud.Bindings.ImPlot; +using Dalamud.Interface.ImGuiBackend.Delegates; using Dalamud.Interface.ImGuiBackend.Helpers; using Dalamud.Interface.ImGuiBackend.InputHandler; using Dalamud.Interface.ImGuiBackend.Renderers; @@ -93,13 +94,13 @@ internal sealed unsafe class Dx11Win32Backend : IWin32Backend ~Dx11Win32Backend() => this.ReleaseUnmanagedResources(); /// - public event IImGuiBackend.BuildUiDelegate? BuildUi; + public event ImGuiBuildUiDelegate? BuildUi; /// - public event IImGuiBackend.NewInputFrameDelegate? NewInputFrame; + public event ImGuiNewInputFrameDelegate? NewInputFrame; /// - public event IImGuiBackend.NewRenderFrameDelegate? NewRenderFrame; + public event ImGuiNewRenderFrameDelegate? NewRenderFrame; /// public bool UpdateCursor diff --git a/Dalamud/Interface/ImGuiBackend/IImGuiBackend.cs b/Dalamud/Interface/ImGuiBackend/IImGuiBackend.cs index 9248b4b5a..4a41191b5 100644 --- a/Dalamud/Interface/ImGuiBackend/IImGuiBackend.cs +++ b/Dalamud/Interface/ImGuiBackend/IImGuiBackend.cs @@ -1,4 +1,5 @@ -using Dalamud.Interface.ImGuiBackend.InputHandler; +using Dalamud.Interface.ImGuiBackend.Delegates; +using Dalamud.Interface.ImGuiBackend.InputHandler; using Dalamud.Interface.ImGuiBackend.Renderers; namespace Dalamud.Interface.ImGuiBackend; @@ -6,23 +7,14 @@ namespace Dalamud.Interface.ImGuiBackend; /// Backend for ImGui. internal interface IImGuiBackend : IDisposable { - /// Delegate to be called when ImGui should be used to layout now. - public delegate void BuildUiDelegate(); - - /// Delegate to be called on new input frame. - public delegate void NewInputFrameDelegate(); - - /// Delegaet to be called on new render frame. - public delegate void NewRenderFrameDelegate(); - /// User methods invoked every ImGui frame to construct custom UIs. - event BuildUiDelegate? BuildUi; + event ImGuiBuildUiDelegate? BuildUi; /// User methods invoked every ImGui frame on handling inputs. - event NewInputFrameDelegate? NewInputFrame; + event ImGuiNewInputFrameDelegate? NewInputFrame; /// User methods invoked every ImGui frame on handling renders. - event NewRenderFrameDelegate? NewRenderFrame; + event ImGuiNewRenderFrameDelegate? NewRenderFrame; /// Gets or sets a value indicating whether the cursor should be overridden with the ImGui cursor. /// @@ -36,7 +28,7 @@ internal interface IImGuiBackend : IDisposable /// Gets the input handler. IImGuiInputHandler InputHandler { get; } - + /// Gets the renderer. IImGuiRenderer Renderer { get; } @@ -45,7 +37,7 @@ internal interface IImGuiBackend : IDisposable /// Handles stuff before resizing happens. void OnPreResize(); - + /// Handles stuff after resizing happens. /// The new width. /// The new height. diff --git a/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs b/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs index b3316abca..a76eb1703 100644 --- a/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs +++ b/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs @@ -374,6 +374,14 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler case WM.WM_DISPLAYCHANGE: this.viewportHandler.UpdateMonitors(); break; + + case WM.WM_KILLFOCUS when hWndCurrent == this.hWnd: + if (!ImGui.IsAnyMouseDown() && GetCapture() == hWndCurrent) + ReleaseCapture(); + + ImGui.GetIO().WantCaptureMouse = false; + ImGui.ClearWindowFocus(); + break; } return null; diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs index 72c964062..e94501d92 100644 --- a/Dalamud/Interface/Internal/InterfaceManager.cs +++ b/Dalamud/Interface/Internal/InterfaceManager.cs @@ -18,6 +18,7 @@ using Dalamud.Hooking; using Dalamud.Hooking.Internal; using Dalamud.Hooking.WndProcHook; using Dalamud.Interface.ImGuiBackend; +using Dalamud.Interface.ImGuiBackend.Delegates; using Dalamud.Interface.ImGuiNotification; using Dalamud.Interface.ImGuiNotification.Internal; using Dalamud.Interface.Internal.Asserts; @@ -128,7 +129,7 @@ internal partial class InterfaceManager : IInternalDisposableService /// /// This event gets called each frame to facilitate ImGui drawing. /// - public event IImGuiBackend.BuildUiDelegate? Draw; + public event ImGuiBuildUiDelegate? Draw; /// /// This event gets called when ResizeBuffers is called. diff --git a/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.ComboAndList.cs b/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.ComboAndList.cs index 4b3e99a3b..4d582b4d0 100644 --- a/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.ComboAndList.cs +++ b/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.ComboAndList.cs @@ -349,7 +349,7 @@ public static unsafe partial class ImGui s.Item2 = s.Item1.Invoke(ref s.Item3, index); if (s.Item2.IsNull) return false; - *text = (byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in s.Item2.Span[0])); + *text = (byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in s.Item2.GetPinnableNullTerminatedReference())); return true; #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type } @@ -363,7 +363,7 @@ public static unsafe partial class ImGui s.Item2 = s.Item1.Invoke(s.Item3, index); if (s.Item2.IsNull) return false; - *text = (byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in s.Item2.Span[0])); + *text = (byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in s.Item2.GetPinnableNullTerminatedReference())); return true; #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type } @@ -377,7 +377,7 @@ public static unsafe partial class ImGui s.Item2 = s.Item1.Invoke(index); if (s.Item2.IsNull) return false; - *text = (byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in s.Item2.Span[0])); + *text = (byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in s.Item2.GetPinnableNullTerminatedReference())); return true; #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type }