fix(ui): #409 tooltip review fix round — F1-F11
Opus review of a377b9bf returned architectural PASS-with-findings /
retail-fidelity FAIL with F1-F12 (F12 info-only). All eleven fixed,
each re-derived against docs/research/named-retail/acclient_2013_pseudo_c.txt:
- F1 PositionAtMouse: retail offsets BOTH axes +32px before the clamp
(StartTooltip @0x00459700, @0x00459739/@0x00459747) — was landing
flush at the cursor.
- F2 UiRoot: the dwell timer now anchors to mouse-IDLE like retail's
m_lastMouseMoveTime (MouseMoveHandler @0x0045E710), resetting on
every move within the same widget while !_tooltipFired, not just on
hover-enter.
- F3 register TS-85 rewritten: the "dynamic InqProperty(0x49) override"
framing was false — UIElement::InqProperty @0x004638D0's base impl
reads the same authored bags this port already reads. The real
second text source (m_TTText/SetTooltip, headed by the P0xD0
truncated-text auto-tooltip @0x00466F80) needs a per-line-position
truncation model UiText doesn't have — sized disproportionate for
this round and left honestly deferred rather than stubbed.
- F4 OnTooltipShow: null LayoutPolicy + Anchors=None on the popup root
and text child before resizing, mirroring RetailMessageDialogView's
sibling shape.
- F5 OnTooltipShow: return without mounting when the P0x4A text child
doesn't resolve to a UiText (retail's DynamicCast gate,
StartTooltip @0x0045DE90 @0x0045df65/@0x0045df6f) — was mounting an
empty 30x30 bevel artifact.
- F6 UiRoot.Tick: the dwell-arm branch now requires Captured is null
(CheckTooltip @0x0045B6E0 @0x0045b715) — a widget hovered before a
drag/resize/capture began must not pop mid-gesture.
- F7 UiRoot.ReleaseCapture: no longer resets _tooltipFired
(ReleaseMouseCapture @0x0045D2B0 touches only the idle timestamp) —
a mouse-up while a tooltip is shown no longer tears it down and
silently re-fires it 250ms later.
- F8 ApplyTooltipText: applies ResizeTo's own max/min width/height
clamps (P0x3C/0x3D/0x3E/0x3F, @0x00463C30) before assigning the
grown size; zeroes text.Padding to keep the measured size margin-
comparable. New ElementInfo/UiElement plumbing for the four
properties, same shape as the existing tooltip fields.
- F9 doc precision: sweep counts corrected 434->430 / 191->187 (live-
DAT re-measured), the "243 showable" claim now measured exactly
(not assumed) via a new Showable column in the sweep test, and the
MiscSettings citation split into its two real mechanisms
(RegisterPreference in Init vs. AttachPreference/SetPreferenceRange
elsewhere).
- F10 register AD-106: the topmost guarantee is versus dialogs/screens
only (the overlay popup layer and drag ghost still paint above
regardless), and the per-tick BringToFront ratchet has four rungs,
not three.
- F11 RetailUiRuntime.ResetSessionDialogs: now also calls the new
UiRoot.ResetTooltipTracking() so a post-reset hover re-shows
immediately instead of waiting out the stale fired-latch.
New pinning tests (RetailTooltipPresenterTests: F1/F2/F5/F6/F7/F8) each
verified to fail against the pre-fix behavior via a temporary revert-
and-rerun before being confirmed against the restored fix.
PortalProjectionTests.ProjectToClipLease_ReusesPooledWorkWithoutResultArrays
recurrence logged on issue #346 (already the tracking issue for this
load-sensitive flake) — hit twice under load this review, standalone
26/26, unrelated to #409.
Gates: Release build 0 errors; App suite (live-DAT env) 5416/5413
passed/3 skips (was 5410/5407/3, +6 new tests); Runtime 1735/0;
UI.Abstractions 926/0; full solution (no env, 69 skips expected)
14,623/14,554 passed/69 skipped/0 failed (was 14,617/14,548, +6).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
a377b9bff7
commit
2719782dc0
11 changed files with 515 additions and 58 deletions
|
|
@ -107,10 +107,10 @@ horizontal `HJustify` mapping while in this code, since it shares the
|
|||
|
||||
## #409 — Client-wide UI tooltip system is unshipped (GF-16, deferred out of Campaign CC gate round 1)
|
||||
|
||||
**Status:** CODE-COMPLETE 2026-08-16 (this commit) — pending the user's connected visual gate (see the gate note at the bottom of this entry).
|
||||
**Status:** CODE-COMPLETE 2026-08-16, review-fix round F1-F11 landed same day (`fix(ui): #409 tooltip review fix round`) — pending the user's connected visual gate (see the gate note at the bottom of this entry).
|
||||
**Severity:** LOW-MEDIUM (cosmetic/discoverability — no gameplay impact, but retail shows a tooltip on hover for authored elements client-wide and acdream showed none before this fix)
|
||||
|
||||
**2026-08-16 re-derivation + port (this commit).** Full re-derivation from
|
||||
**2026-08-16 re-derivation + port.** Full re-derivation from
|
||||
`docs/research/named-retail/acclient_2013_pseudo_c.txt` corrected two things
|
||||
the original GF-16 filing below got wrong from a shallower pass: **`P0x47`
|
||||
is NOT a "tooltip behavior enum" — it is the element-desc id WITHIN the
|
||||
|
|
@ -119,11 +119,40 @@ popup LayoutDesc (`P0x48`) to instantiate as the popup's root**
|
|||
`LayoutDesc::AccessElementDesc`), and **`P0x4A` is read off the freshly
|
||||
INSTANTIATED popup's own root element, not the hovering trigger element**
|
||||
(it names that popup's text-child id). A live-DAT sweep (installed EoR
|
||||
build) found **434 elements author at least one of the five trigger
|
||||
build) found **430 elements author at least one of the five trigger
|
||||
properties** (243 with literal `P0x49` `StringInfo` text this port shows;
|
||||
the other 191 rely on retail's DYNAMIC `InqProperty(0x49)` text override,
|
||||
out of scope — see register row TS-85), superseding the original "~253"
|
||||
estimate. Layout `0x21000041` holds four 30x30 popup skins
|
||||
the other 187 have no literal text and show nothing — see register row
|
||||
TS-85 for the honest scope of what's missing there), superseding the
|
||||
original "~253" estimate.
|
||||
|
||||
**2026-08-16 review-fix round (F1-F11), same day.** An Opus review of the
|
||||
port above returned architectural PASS-with-findings / retail-fidelity FAIL
|
||||
with twelve findings; F1-F11 landed in one fix commit (F12 was info-only).
|
||||
Highlights: the popup now offsets +32px from the mouse on both axes
|
||||
(`StartTooltip @0x00459700`, was landing flush at the cursor); the dwell
|
||||
timer now anchors to mouse-IDLE like retail's `m_lastMouseMoveTime`, not
|
||||
hover-enter, and is gated off while the mouse has capture
|
||||
(`CheckTooltip @0x0045B6E0`); `ReleaseCapture` no longer tears down an
|
||||
already-shown tooltip's fired latch (it only restarts the idle deadline,
|
||||
matching `ReleaseMouseCapture @0x0045D2B0`); the popup no longer mounts an
|
||||
empty bevel artifact when its text child fails to resolve
|
||||
(`StartTooltip @0x0045DE90`'s `DynamicCast` gate); the popup and its text
|
||||
child now null their anchor policy before resizing, mirroring the sibling
|
||||
`RetailMessageDialogView`; the auto-resize now applies retail's
|
||||
`ResizeTo @0x00463C30` max/min width/height clamps; and a session reset now
|
||||
also clears `UiRoot`'s own hover/tooltip-fired latch (not just the
|
||||
presenter's popup element) so a post-reset hover re-shows immediately. The
|
||||
review's biggest correction was to the ORIGINAL port's own framing of what
|
||||
it deferred: "191 elements rely on retail's dynamic `InqProperty(0x49)`
|
||||
override" was FALSE — retail's own base `InqProperty` reads the same
|
||||
authored property bags this port already reads, so most no-literal-text
|
||||
elements show nothing in retail too. Register row TS-85 is rewritten (not
|
||||
just re-counted) with the real gap: the `m_TTText`/`SetTooltip` runtime-text
|
||||
family, headed by the `P0xD0` truncated-text auto-tooltip
|
||||
(`UIElement_Text::RecalculateTruncation @0x00466F80`) — sized and found
|
||||
disproportionate to port in the same round (it needs a per-line-position
|
||||
truncation model this port's `UiText` doesn't have), so it stays deferred,
|
||||
honestly described. Layout `0x21000041` holds four 30x30 popup skins
|
||||
(`0x10000487`/`0x10000395`/`0x10000397`/`0x10000398`), each a four-piece
|
||||
bevel frame around one shared Type-12 text child `0x10000396` — confirmed
|
||||
by `TooltipLiveDatTests`.
|
||||
|
|
@ -152,11 +181,20 @@ already drives dismissal, and it no-ops when the hit-tested element hasn't
|
|||
changed, so retail itself does not dismiss a tooltip by clicking its own
|
||||
owner.
|
||||
|
||||
**Deferred (register TS-85):** dynamic per-element tooltip text
|
||||
(`InqProperty(0x49)`, 191 elements) and the `P0x3D` per-element wrap-width
|
||||
override (zero elements author one today). **Deferred (register AD-106):**
|
||||
the topmost-z-order mechanism is a sibling-with-later-reraise adaptation,
|
||||
not retail's literal separate presentation layer.
|
||||
**Deferred (register TS-85, rewritten at the F3 review round):** the
|
||||
`m_TTText`/`SetTooltip` runtime-text family headed by the `P0xD0`
|
||||
truncated-text auto-tooltip (187 of 430 tooltip-property-authoring elements
|
||||
have no literal text and show nothing; an unmeasured subset of those would
|
||||
show retail's truncation tooltip instead) and the `P0x3D` per-element
|
||||
wrap-width override (zero elements author one today). **Deferred (register
|
||||
AD-106, two honest additions at the F10 review round):** the topmost-z-order
|
||||
mechanism is a sibling-with-later-reraise adaptation, not retail's literal
|
||||
separate presentation layer — the guarantee is versus dialogs/screens ONLY
|
||||
(the overlay popup layer and the drag ghost still paint above regardless),
|
||||
and the per-tick `BringToFront` re-raise chain now has four rungs
|
||||
(`CharacterManagementUiController`, `CharacterCreationUiController`,
|
||||
`RetailDialogFactory`, `RetailTooltipPresenter`) — bounded and enumerable
|
||||
today, but a design smell worth flagging.
|
||||
|
||||
**Gate note (5-10 min, `ACDREAM_RETAIL_UI=1`):** hover the mouse over any
|
||||
of these and hold still — a small tooltip box should appear after a brief
|
||||
|
|
@ -2893,6 +2931,18 @@ two subsequent full runs. Same FILE as #302 but a DIFFERENT test — filed
|
|||
separately per the never-conflate rule.
|
||||
**Filed:** 2026-08-08, observed during #344's suite runs.
|
||||
|
||||
**2026-08-16 recurrence (Campaign #409 tooltip review-fix round).** The Opus
|
||||
reviewer of `a377b9bf` hit this same assertion failing TWICE under
|
||||
full-solution load, unrelated to any #409 tooltip code; passes standalone
|
||||
26/26. Joining the same running known-flake set the CC7 gate row already
|
||||
names (`docs/plans/2026-08-15-character-creation-campaign.md`, CC7 row) for
|
||||
Core.Net `NakEmissionTests.LossSoak_...` / Content `DecodedTextureCacheTests`
|
||||
/ App `SocialPanelLiveMountProbeTests.ProbeLiveMountShapes` /
|
||||
`RuntimeCollisionReportingStateTests.WarmedSteadyContactRefreshDoesNotAllocate` —
|
||||
a full-solution gate hitting exactly one of these five allocation/timing-
|
||||
sensitive tests, with a clean standalone or immediate-rerun pass, is this
|
||||
known class, not a new regression.
|
||||
|
||||
---
|
||||
|
||||
## #344 — Mid-teleport crash: world-frame owners disagree during a long portal into a dungeon
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue