From 5931f2f30141b84a3efbeb03bc3ae2715ef98419 Mon Sep 17 00:00:00 2001 From: JonKazama-Hellion Date: Fri, 8 May 2026 21:42:57 +0200 Subject: [PATCH] Use sync FontManager allocation in LoadAsync to avoid first-draw race MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous fire-and-forget Task.Run pattern could leave Plugin.FontManager null when the first UiBuilder.Draw tick fires (ChatLogWindow dereferences FontManager.FontAwesome / RegularFont / ItalicFont in its draw paths). Allocate FontManager and call BuildFonts() synchronously, mirroring ChatTwo Plugin.cs:152. BuildFonts itself is non-blocking — it just registers IFontHandles with Dalamud's atlas; the actual atlas rebuild runs on Dalamud's pipeline a few frames later, so the perceived-load win still holds (LoadAsync no longer waits for atlas build). BuildFontsAsync in FontManager.cs stays for the Settings-driven manual rebuild path. --- HellionChat/Plugin.cs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/HellionChat/Plugin.cs b/HellionChat/Plugin.cs index a31ab28..41c63a1 100755 --- a/HellionChat/Plugin.cs +++ b/HellionChat/Plugin.cs @@ -471,18 +471,15 @@ public sealed class Plugin : IAsyncDalamudPlugin cancellationToken.ThrowIfCancellationRequested(); - // Font-build runs fire-and-forget. The atlas rebuild lands a few - // hundred ms after LoadAsync returns; first frames draw with - // Dalamud's default font until the Hellion-Exo2 / NotoSans handles - // are ready, then ImGui switches to the custom fonts (visible - // "font-pop"). Mirrors ChatTwo's pattern — perceived-load win - // comes from "Finished loading" landing earlier, not from a faster - // atlas build. - _ = Task.Run(async () => - { - FontManager = new FontManager(); - await FontManager.BuildFontsAsync(cancellationToken).ConfigureAwait(false); - }, cancellationToken); + // Sync allocation + handle registration. BuildFonts() registers + // IFontHandles with Dalamud's UiBuilder.FontAtlas — registration + // itself is non-blocking (handles stored, lambdas queued). Dalamud + // rebuilds the atlas on its own pipeline a few frames later; first + // frames render with the default font until the rebuild lands and + // ImGui switches to Hellion-Exo2 / NotoSans (visible "font-pop"). + // Mirrors ChatTwo Plugin.cs:152. + FontManager = new FontManager(); + FontManager.BuildFonts(); // Theme init stays sync on the LoadAsync continuation — cheap, // and Active is read every Draw frame, so the registry must be