diff --git a/HellionChat/Plugin.cs b/HellionChat/Plugin.cs index cc2a810..a0cf891 100755 --- a/HellionChat/Plugin.cs +++ b/HellionChat/Plugin.cs @@ -241,6 +241,13 @@ public sealed class Plugin : IAsyncDalamudPlugin // TempTabs survive reload — Jin's tester feedback (v1.4.7). Config.Tabs.RemoveAll(TabLifecycleHelpers.ShouldStripOnLoad); + // GP-04: clear stale Tab.PopOut flags now — the pool binds further down + // (ChannelPopoutPool resolve below), so at this point no tab can own a + // slot. A persisted PopOut=true (notably on surviving pinned TempTabs) + // would otherwise be a flag with no window. Runs after the strip, before + // any pool TryOpen. + TabLifecycleHelpers.ResetPopOutOnLoad(Config.Tabs); + LanguageChanged(Interface.UiLanguage); // v1.5.3 migration: Settings.Apply auto-activates the matching diff --git a/HellionChat/Util/TabLifecycleHelpers.cs b/HellionChat/Util/TabLifecycleHelpers.cs index dc87ae2..d95ddcb 100644 --- a/HellionChat/Util/TabLifecycleHelpers.cs +++ b/HellionChat/Util/TabLifecycleHelpers.cs @@ -17,6 +17,19 @@ internal static class TabLifecycleHelpers public static bool ShouldStripOnSave(Tab t) => IsInUnpinnedPool(t); + // GP-04: clear every Tab.PopOut at load time. The pool binds later, so at + // load NO tab can own a slot — a persisted PopOut=true is always a stale flag + // with no window. Unconditional (pinned included) because pinned TempTabs + // survive the load and are the main stale-flag source; a !IsPinned filter + // would leave exactly those leaking. Lockstep with the two in-memory resets + // (AutoTellTabsService pool-full + Configuration.UpdateFrom backToOriginal). + // TEST-MIRROR: ../../../Hellion Build test/_Helpers/PopOutResetOnLoadTests.cs + internal static void ResetPopOutOnLoad(IEnumerable tabs) + { + foreach (var tab in tabs) + tab.PopOut = false; + } + // Stale-tell strip + channel derive, run at every tab activation. When a // DIFFERENT tab becomes the input surface, drop any runtime tell state the // game-side detour left on it (the CurrentChannel tell target plus the