Fix combobox callback impl (#2347)

* Fix combobox callback impl

* Make ImGuiBackend delegates public

* Release ImGui focus when the game window loses focus
This commit is contained in:
srkizer 2025-08-07 11:18:40 +09:00 committed by GitHub
parent 27f924f3b1
commit 1f06006cc0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 36 additions and 22 deletions

View file

@ -0,0 +1,4 @@
namespace Dalamud.Interface.ImGuiBackend.Delegates;
/// <summary>Delegate to be called when ImGui should be used to layout now.</summary>
public delegate void ImGuiBuildUiDelegate();

View file

@ -0,0 +1,4 @@
namespace Dalamud.Interface.ImGuiBackend.Delegates;
/// <summary>Delegate to be called on new input frame.</summary>
public delegate void ImGuiNewInputFrameDelegate();

View file

@ -0,0 +1,4 @@
namespace Dalamud.Interface.ImGuiBackend.Delegates;
/// <summary>Delegate to be called on new render frame.</summary>
public delegate void ImGuiNewRenderFrameDelegate();

View file

@ -8,6 +8,7 @@ using System.Runtime.InteropServices;
using Dalamud.Bindings.ImGui; using Dalamud.Bindings.ImGui;
using Dalamud.Bindings.ImGuizmo; using Dalamud.Bindings.ImGuizmo;
using Dalamud.Bindings.ImPlot; using Dalamud.Bindings.ImPlot;
using Dalamud.Interface.ImGuiBackend.Delegates;
using Dalamud.Interface.ImGuiBackend.Helpers; using Dalamud.Interface.ImGuiBackend.Helpers;
using Dalamud.Interface.ImGuiBackend.InputHandler; using Dalamud.Interface.ImGuiBackend.InputHandler;
using Dalamud.Interface.ImGuiBackend.Renderers; using Dalamud.Interface.ImGuiBackend.Renderers;
@ -93,13 +94,13 @@ internal sealed unsafe class Dx11Win32Backend : IWin32Backend
~Dx11Win32Backend() => this.ReleaseUnmanagedResources(); ~Dx11Win32Backend() => this.ReleaseUnmanagedResources();
/// <inheritdoc/> /// <inheritdoc/>
public event IImGuiBackend.BuildUiDelegate? BuildUi; public event ImGuiBuildUiDelegate? BuildUi;
/// <inheritdoc/> /// <inheritdoc/>
public event IImGuiBackend.NewInputFrameDelegate? NewInputFrame; public event ImGuiNewInputFrameDelegate? NewInputFrame;
/// <inheritdoc/> /// <inheritdoc/>
public event IImGuiBackend.NewRenderFrameDelegate? NewRenderFrame; public event ImGuiNewRenderFrameDelegate? NewRenderFrame;
/// <inheritdoc/> /// <inheritdoc/>
public bool UpdateCursor public bool UpdateCursor

View file

@ -1,4 +1,5 @@
using Dalamud.Interface.ImGuiBackend.InputHandler; using Dalamud.Interface.ImGuiBackend.Delegates;
using Dalamud.Interface.ImGuiBackend.InputHandler;
using Dalamud.Interface.ImGuiBackend.Renderers; using Dalamud.Interface.ImGuiBackend.Renderers;
namespace Dalamud.Interface.ImGuiBackend; namespace Dalamud.Interface.ImGuiBackend;
@ -6,23 +7,14 @@ namespace Dalamud.Interface.ImGuiBackend;
/// <summary>Backend for ImGui.</summary> /// <summary>Backend for ImGui.</summary>
internal interface IImGuiBackend : IDisposable internal interface IImGuiBackend : IDisposable
{ {
/// <summary>Delegate to be called when ImGui should be used to layout now.</summary>
public delegate void BuildUiDelegate();
/// <summary>Delegate to be called on new input frame.</summary>
public delegate void NewInputFrameDelegate();
/// <summary>Delegaet to be called on new render frame.</summary>
public delegate void NewRenderFrameDelegate();
/// <summary>User methods invoked every ImGui frame to construct custom UIs.</summary> /// <summary>User methods invoked every ImGui frame to construct custom UIs.</summary>
event BuildUiDelegate? BuildUi; event ImGuiBuildUiDelegate? BuildUi;
/// <summary>User methods invoked every ImGui frame on handling inputs.</summary> /// <summary>User methods invoked every ImGui frame on handling inputs.</summary>
event NewInputFrameDelegate? NewInputFrame; event ImGuiNewInputFrameDelegate? NewInputFrame;
/// <summary>User methods invoked every ImGui frame on handling renders.</summary> /// <summary>User methods invoked every ImGui frame on handling renders.</summary>
event NewRenderFrameDelegate? NewRenderFrame; event ImGuiNewRenderFrameDelegate? NewRenderFrame;
/// <summary>Gets or sets a value indicating whether the cursor should be overridden with the ImGui cursor. /// <summary>Gets or sets a value indicating whether the cursor should be overridden with the ImGui cursor.
/// </summary> /// </summary>
@ -36,7 +28,7 @@ internal interface IImGuiBackend : IDisposable
/// <summary>Gets the input handler.</summary> /// <summary>Gets the input handler.</summary>
IImGuiInputHandler InputHandler { get; } IImGuiInputHandler InputHandler { get; }
/// <summary>Gets the renderer.</summary> /// <summary>Gets the renderer.</summary>
IImGuiRenderer Renderer { get; } IImGuiRenderer Renderer { get; }
@ -45,7 +37,7 @@ internal interface IImGuiBackend : IDisposable
/// <summary>Handles stuff before resizing happens.</summary> /// <summary>Handles stuff before resizing happens.</summary>
void OnPreResize(); void OnPreResize();
/// <summary>Handles stuff after resizing happens.</summary> /// <summary>Handles stuff after resizing happens.</summary>
/// <param name="newWidth">The new width.</param> /// <param name="newWidth">The new width.</param>
/// <param name="newHeight">The new height.</param> /// <param name="newHeight">The new height.</param>

View file

@ -374,6 +374,14 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
case WM.WM_DISPLAYCHANGE: case WM.WM_DISPLAYCHANGE:
this.viewportHandler.UpdateMonitors(); this.viewportHandler.UpdateMonitors();
break; break;
case WM.WM_KILLFOCUS when hWndCurrent == this.hWnd:
if (!ImGui.IsAnyMouseDown() && GetCapture() == hWndCurrent)
ReleaseCapture();
ImGui.GetIO().WantCaptureMouse = false;
ImGui.ClearWindowFocus();
break;
} }
return null; return null;

View file

@ -18,6 +18,7 @@ using Dalamud.Hooking;
using Dalamud.Hooking.Internal; using Dalamud.Hooking.Internal;
using Dalamud.Hooking.WndProcHook; using Dalamud.Hooking.WndProcHook;
using Dalamud.Interface.ImGuiBackend; using Dalamud.Interface.ImGuiBackend;
using Dalamud.Interface.ImGuiBackend.Delegates;
using Dalamud.Interface.ImGuiNotification; using Dalamud.Interface.ImGuiNotification;
using Dalamud.Interface.ImGuiNotification.Internal; using Dalamud.Interface.ImGuiNotification.Internal;
using Dalamud.Interface.Internal.Asserts; using Dalamud.Interface.Internal.Asserts;
@ -128,7 +129,7 @@ internal partial class InterfaceManager : IInternalDisposableService
/// <summary> /// <summary>
/// This event gets called each frame to facilitate ImGui drawing. /// This event gets called each frame to facilitate ImGui drawing.
/// </summary> /// </summary>
public event IImGuiBackend.BuildUiDelegate? Draw; public event ImGuiBuildUiDelegate? Draw;
/// <summary> /// <summary>
/// This event gets called when ResizeBuffers is called. /// This event gets called when ResizeBuffers is called.

View file

@ -349,7 +349,7 @@ public static unsafe partial class ImGui
s.Item2 = s.Item1.Invoke(ref s.Item3, index); s.Item2 = s.Item1.Invoke(ref s.Item3, index);
if (s.Item2.IsNull) if (s.Item2.IsNull)
return false; 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; return true;
#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type #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); s.Item2 = s.Item1.Invoke(s.Item3, index);
if (s.Item2.IsNull) if (s.Item2.IsNull)
return false; 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; return true;
#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type #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); s.Item2 = s.Item1.Invoke(index);
if (s.Item2.IsNull) if (s.Item2.IsNull)
return false; 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; return true;
#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
} }