diff --git a/Dalamud/Interface/Internal/DalamudIme.cs b/Dalamud/Interface/Internal/DalamudIme.cs
index 28a9075bd..1ee248b17 100644
--- a/Dalamud/Interface/Internal/DalamudIme.cs
+++ b/Dalamud/Interface/Internal/DalamudIme.cs
@@ -11,6 +11,7 @@ using System.Text.Unicode;
using Dalamud.Game.Text;
using Dalamud.Hooking.WndProcHook;
using Dalamud.Interface.GameFonts;
+using Dalamud.Interface.Internal.ManagedAsserts;
using Dalamud.Interface.ManagedFontAtlas.Internals;
using Dalamud.Interface.Utility;
@@ -28,7 +29,6 @@ namespace Dalamud.Interface.Internal;
[ServiceManager.BlockingEarlyLoadedService]
internal sealed unsafe class DalamudIme : IDisposable, IServiceType
{
- private const int ImGuiContextTextStateOffset = 0x4588;
private const int CImGuiStbTextCreateUndoOffset = 0xB57A0;
private const int CImGuiStbTextUndoOffset = 0xB59C0;
@@ -178,7 +178,7 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
internal char InputModeIcon { get; private set; }
private static ImGuiInputTextState* TextState =>
- (ImGuiInputTextState*)(ImGui.GetCurrentContext() + ImGuiContextTextStateOffset);
+ (ImGuiInputTextState*)(ImGui.GetCurrentContext() + ImGuiContextOffsets.TextStateOffset);
///
public void Dispose()
diff --git a/Dalamud/Interface/Internal/ImGuiClipboardFunctionProvider.cs b/Dalamud/Interface/Internal/ImGuiClipboardFunctionProvider.cs
index 1746fb1c4..bbf665405 100644
--- a/Dalamud/Interface/Internal/ImGuiClipboardFunctionProvider.cs
+++ b/Dalamud/Interface/Internal/ImGuiClipboardFunctionProvider.cs
@@ -52,7 +52,6 @@ internal sealed unsafe class ImGuiClipboardFunctionProvider : IServiceType, IDis
private ImGuiClipboardFunctionProvider(InterfaceManager.InterfaceManagerWithScene imws)
{
// Effectively waiting for ImGui to become available.
- _ = imws;
Debug.Assert(ImGuiHelpers.IsImGuiInitialized, "IMWS initialized but IsImGuiInitialized is false?");
var io = ImGui.GetIO();
diff --git a/Dalamud/Interface/Internal/ImGuiDrawListFixProvider.cs b/Dalamud/Interface/Internal/ImGuiDrawListFixProvider.cs
new file mode 100644
index 000000000..cdf7ab23e
--- /dev/null
+++ b/Dalamud/Interface/Internal/ImGuiDrawListFixProvider.cs
@@ -0,0 +1,124 @@
+using System.Diagnostics;
+using System.Linq;
+using System.Numerics;
+
+using Dalamud.Hooking;
+
+using ImGuiNET;
+
+namespace Dalamud.Interface.Internal;
+
+///
+/// Fixes ImDrawList not correctly dealing with the current texture for that draw list not in tune with the global
+/// state. Currently, ImDrawList::AddPolyLine and ImDrawList::AddRectFilled are affected.
+///
+/// * The implementation for AddRectFilled is entirely replaced with the hook below.
+/// * The implementation for AddPolyLine is wrapped with Push/PopTextureID.
+///
+/// TODO:
+/// * imgui_draw.cpp:1433 ImDrawList::AddRectFilled
+/// The if block needs a PushTextureID(_Data->TexIdCommon)/PopTextureID() block,
+/// if _Data->TexIdCommon != _CmdHeader.TextureId.
+/// * imgui_draw.cpp:729 ImDrawList::AddPolyLine
+/// The if block always needs to call PushTextureID if the abovementioned condition is not met.
+/// Change push_texture_id to only have one condition.
+///
+[ServiceManager.EarlyLoadedService]
+internal sealed unsafe class ImGuiDrawListFixProvider : IServiceType, IDisposable
+{
+ private const int CImGuiImDrawListAddPolyLineOffset = 0x589B0;
+ private const int CImGuiImDrawListAddRectFilled = 0x59FD0;
+ private const int CImGuiImDrawListSharedDataTexIdCommonOffset = 0;
+
+ private readonly Hook hookImDrawListAddPolyline;
+ private readonly Hook hookImDrawListAddRectFilled;
+
+ [ServiceManager.ServiceConstructor]
+ private ImGuiDrawListFixProvider(InterfaceManager.InterfaceManagerWithScene imws)
+ {
+ // Force cimgui.dll to be loaded.
+ _ = ImGui.GetCurrentContext();
+ var cimgui = Process.GetCurrentProcess().Modules.Cast()
+ .First(x => x.ModuleName == "cimgui.dll")
+ .BaseAddress;
+
+ this.hookImDrawListAddPolyline = Hook.FromAddress(
+ cimgui + CImGuiImDrawListAddPolyLineOffset,
+ this.ImDrawListAddPolylineDetour);
+ this.hookImDrawListAddRectFilled = Hook.FromAddress(
+ cimgui + CImGuiImDrawListAddRectFilled,
+ this.ImDrawListAddRectFilledDetour);
+ this.hookImDrawListAddPolyline.Enable();
+ this.hookImDrawListAddRectFilled.Enable();
+ }
+
+ private delegate void ImDrawListAddPolyLine(
+ ImDrawListPtr drawListPtr,
+ ref Vector2 points,
+ int pointsCount,
+ uint color,
+ ImDrawFlags flags,
+ float thickness);
+
+ private delegate void ImDrawListAddRectFilled(
+ ImDrawListPtr drawListPtr,
+ ref Vector2 min,
+ ref Vector2 max,
+ uint col,
+ float rounding,
+ ImDrawFlags flags);
+
+ ///
+ public void Dispose()
+ {
+ this.hookImDrawListAddPolyline.Dispose();
+ this.hookImDrawListAddRectFilled.Dispose();
+ }
+
+ private void ImDrawListAddRectFilledDetour(
+ ImDrawListPtr drawListPtr,
+ ref Vector2 min,
+ ref Vector2 max,
+ uint col,
+ float rounding,
+ ImDrawFlags flags)
+ {
+ if (rounding < 0 || (flags & ImDrawFlags.RoundCornersMask) == ImDrawFlags.RoundCornersMask)
+ {
+ var texIdCommon = *(nint*)(drawListPtr._Data + CImGuiImDrawListSharedDataTexIdCommonOffset);
+ var pushTextureId = texIdCommon != drawListPtr._CmdHeader.TextureId;
+ if (pushTextureId)
+ drawListPtr.PushTextureID(texIdCommon);
+
+ drawListPtr.PrimReserve(6, 4);
+ drawListPtr.PrimRect(min, max, col);
+
+ if (pushTextureId)
+ drawListPtr.PopTextureID();
+ }
+ else
+ {
+ drawListPtr.PathRect(min, max, rounding, flags);
+ drawListPtr.PathFillConvex(col);
+ }
+ }
+
+ private void ImDrawListAddPolylineDetour(
+ ImDrawListPtr drawListPtr,
+ ref Vector2 points,
+ int pointsCount,
+ uint color,
+ ImDrawFlags flags,
+ float thickness)
+ {
+ var texIdCommon = *(nint*)(drawListPtr._Data + CImGuiImDrawListSharedDataTexIdCommonOffset);
+ var pushTextureId = texIdCommon != drawListPtr._CmdHeader.TextureId;
+ if (pushTextureId)
+ drawListPtr.PushTextureID(texIdCommon);
+
+ this.hookImDrawListAddPolyline.Original(drawListPtr, ref points, pointsCount, color, flags, thickness);
+
+ if (pushTextureId)
+ drawListPtr.PopTextureID();
+ }
+}
diff --git a/Dalamud/Interface/Internal/ManagedAsserts/ImGuiContextOffsets.cs b/Dalamud/Interface/Internal/ManagedAsserts/ImGuiContextOffsets.cs
index fd203192f..89e23ab78 100644
--- a/Dalamud/Interface/Internal/ManagedAsserts/ImGuiContextOffsets.cs
+++ b/Dalamud/Interface/Internal/ManagedAsserts/ImGuiContextOffsets.cs
@@ -18,4 +18,6 @@ internal static class ImGuiContextOffsets
public const int FontStackOffset = 0x7A4;
public const int BeginPopupStackOffset = 0x7B8;
+
+ public const int TextStateOffset = 0x4588;
}