Block D of v1.12.0. The line between the two is the whole job, and I got
it wrong once on the way: six cache fields on Tab looked dead because
nothing writes them, and nothing writes them because AutoTellTabTint and
TabTintCache went out with the chat window in cf4705e. Deleting the
fields would have cemented a loss instead of recording a decision.
So they are back, and the sidebar uses them again: an auto-tell tab is
tinted and glyphed from its partner, twelve colours against seven icons.
Four open tells are no longer four identical envelopes in one colour.
Their own header promised the same partner keeps its colour "across
sessions" while hashing with string.GetHashCode, which .NET salts per
process -- every game start reshuffled every tab. FNV-1a now, with a
lowbias32 finalizer that is not decoration: without it a probe over 144
similar keys reached six of the twelve colours, because the caller takes
the low bits with a modulo and FNV leaves those correlated. Three pinned
values guard it, which is also the only assertion that can catch a
regression to a salted hash.
The same question, asked of the three hide conditions this block had
quietly orphaned: HideDuringCutscenes, HideInBattle, HideWhenNotLoggedIn
all had readers in v1.5.6 and lost them in the same commit. Two of them
are states rather than conditions -- a cutscene the user dismissed stays
dismissed until it ends, and combat must not seize a chat that is
already hidden for another reason -- so they come back as a small state
machine with eight pinned transitions, and three toggles whose labels
were already translated in all 25 languages.
Actually deleted, with a reader search each time:
- Six per-tab hide fields. Their reader was the pop-out window and it
stopped consulting them in cf4705e. Per-tab was the wrong unit anyway:
"hide during cutscenes" is a statement about the screen.
- Tab.ChatCodes, whose migration the v16 schema gate had already made
unreachable.
- InactivityHideTimeout and InactivityHideActiveDuringBattle, MaxLinesToRender
which had stopped bounding anything, and the 155 lines of
Configuration.UpdateFrom with no caller at all.
Config version 25, at all three places that carry it. No migration step:
the gate only refuses anything under 16 and Json.NET drops keys it does
not know, so the deleted fields simply stop being written.
One thing a review pass caught that matters more than any of the above:
the clone parity guard had gone hollow. It compares collections by
count, ChatCodes was the only collection the probe seeded, and removing
it left the guard comparing zero against zero. Verified by making
Tab.Clone discard both remaining collections and watching every
assertion stay green. The probe seeds them now, and the same sabotage
fails as it should.
The legacy ChatLogWindow.cs and its tightly coupled neighbours are gone:
PayloadHandler, Popout, ChatInputBar, AutoCompleteInfo, AutoTellTabTint,
the three tab-icon helpers, the old Ui/StatusBar and Ui/SymbolPicker
behind the components-layer replacements, HellionStyle + helpers, the
CompactInputSubmitter test mirror and the QuickPickerSelfTestStep. The
new component layer (MainWindow + the five components + GlobalStyleScope)
now drives the whole chat surface.
InputPreview, CommandHelpWindow and Debugger lose their ChatLogWindow
backref. The first two are skeleton windows for now — DrawConditions
always returns false until the new chat layer exposes equivalent state.
Debugger keeps the current-tab and vanilla-chat blocks; the payload
counters are explicitly marked offline. DbViewer renders Sender/Content
columns as plain TextValue strings instead of the removed DrawChunks.
GameFunctions.Chat and GameFunctions.KeybindManager keep the hook
plumbing intact but mark every ChatLogWindow.Activated /
ChangeTabDelta / TellSpecial site as offline so the FFXIV-side
integration still compiles and runs without an Activated entry point.
TypingIpc.BuildState reports the IPC state as not-typing / not-focused
until the new chat layer surfaces real focus and buffer state again.
Plugin.cs Draw uses StyleEngine.GlobalStyleScope.Push for the per-frame
theme push and stops calling BeginFrame / FinalizeFrame / HideStateCheck
/ DefaultText through the dead window. ImGuiUtil drops PostPayload +
WrapText + the surrounding word-wrap pipeline. PluginHostFactory and
PluginLifecycle drop the legacy DI singletons and AddWindow entries.
Build is clean and csharpier is clean across the trimmed 131-file tree.
- Translated project documentation (LEARNING-JOURNEY, CONTRIBUTORS, AI_DISCLOSURE) to English for better accessibility.
- Standardized internal code documentation by converting XML-doc blocks to standard comment format.
- Cleaned up inline comments and removed redundant versioning metadata across the codebase.
- Refactored non-functional text elements to improve readability and maintain a consistent style.