fix #379: chat opacity fade was scoped to every window, not just chat

Root cause: RetailWindowOpacityController applied the Default/Active
opacity fade to EVERY registered UiRoot window (vitals, toolbar,
inventory, spellbook, radar, even the Options panel itself), but
retail's ChatInterface::SetDefaultOpacity/SetActiveOpacity are only
ever called by gmMainChatUI/gmFloatyChatUI — the mechanism is chat-only
in retail, not a global window-opacity feature.

Fix: scope the controller's catch-up loop, OnWindowRegistered,
ReapplyAll, and Dispose to WindowNames.Chat/ChatWindow1-4 only; every
other registered window now stays fully opaque regardless of slider
position, matching retail's own scope. Regressed by
RetailWindowOpacityControllerTests.
OpacityFade_AppliesOnlyToChatWindows_NeverOtherPanels (registers
vitals/toolbar/chat/a floating chat window and asserts the non-chat
windows never move off 1.0 while chat windows still track Default/
Active correctly).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-11 23:00:57 +02:00
parent c121842664
commit c0b3d8f233
4 changed files with 177 additions and 56 deletions

View file

@ -62,14 +62,36 @@ missing from our template handling.
## #379 — Chat-window opacity applies to ALL retained windows/panels, not only the chat windows
**Status:** OPEN — filed 2026-08-11 at Campaign OP gate 4 (user report:
"When I change the opacity for the chat window only the chatwindows shall
change not the other panels"). Retail's ChatInterface::SetOpacity scopes
the transparency pair to the chat windows; acdream's
`RetailWindowOpacityController` (CH6c) is applying the pair to other
retained panels too. Determine the exact retail scope (main chat + the
four floating chat windows only?) from the decomp before narrowing, then
scope the controller's application set to it.
**Status:** ROOT-CAUSED + FIXED (this commit) — pending the user's
re-gate. Filed 2026-08-11 at Campaign OP gate 4 (user report: "When I
change the opacity for the chat window only the chatwindows shall change
not the other panels").
**ROOT CAUSE — confirmed structural, not just AP-190's known divergence.**
Grepped `acclient_2013_pseudo_c.txt` for every call site of
`ChatInterface::SetDefaultOpacity`/`SetActiveOpacity`: there are exactly
two, `gmFloatyMainChatUI::UpdateFromPlayerModule`/
`RecvNotice_GameplayOptionChanged` (the main chat window) and
`gmFloatyChatUI::UpdateFromPlayerModule` (the four floating windows),
each calling the method on itself. No other `gmPanelUI` sibling derives
from `ChatInterface`, so no other window class even has these methods in
its vtable — retail's scope is structural, not a runtime choice. **Fix:**
`RetailWindowOpacityController` now scopes `Attach`/`OnWindowRegistered`/
`ReapplyAll`/`Dispose` to exactly the five `ChatWindowNames` (main chat +
`ChatWindow1`-`4`) instead of every window `RetailWindowManager`
registers. Register row AP-190 updated in the same commit (the scope
divergence it recorded is now closed; the default-value/easing/focus-
predicate residuals it also recorded are unaffected). Regressed by
`tests/AcDream.App.Tests/UI/RetailWindowOpacityControllerTests.cs`
(`OpacityFade_AppliesOnlyToChatWindows_NeverOtherPanels` pins the exact
applied-window set; the pre-existing tests were updated to register
windows under their real `WindowNames` so the scope check is exercised
by name, matching production).
**Re-gate (§OP5 step 4, rewritten in the gate script): use a chat window
(main or floating) as the "other window," not the toolbar/vitals/another
panel — a non-chat window should now stay fully opaque regardless of the
slider position.**
## #378 — Config-tab dropdown menus render bare (no button well, no arrow) and no popup opens on click