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>
Full re-derivation from named-retail decomp: UIElement::StartTooltipAtMouse
@0x00460D70 -> UIElementManager::StartTooltip @0x0045DE90/@0x00459700,
UIElement::MouseHover @0x00462520 (P0x4B TooltipOn gate + global
m_tooltipEnable), UIElementManager::CheckTooltip @0x0045B6E0 (dwell/
auto-hide timer, default 0.25s/10s), SwitchMouseOver/DeletingElement
(dismissal). Corrects the earlier GF-16 investigation: P0x47 is the
element-desc id WITHIN the popup LayoutDesc (P0x48), not a "behavior
enum"; P0x4A is read off the popup's own instantiated root, not the
trigger element.
- ElementInfo/UiElement gain six tooltip data fields (P0x47/48/49/4A/4B/50),
read generically by ElementReader and copied through LayoutImporter,
mirroring the existing AuthoredInvisible passthrough pattern.
- UiRoot's existing CheckTooltip-derived hover timer gains TooltipShow/
TooltipHide events, a per-element P0x50 delay override, and dismissal
wiring at every retail-confirmed teardown site.
- RetailTooltipPresenter (owned by RetailUiRuntime, mounted alongside
RetailDialogFactory) builds the popup via the existing LayoutImporter
dat-lock seam, auto-resizes by the measured-vs-authored text delta
(word-wrapped via the existing UiText.WrapWords primitive), positions
at the mouse clamped to the display, and stays topmost over dialogs via
its own later per-tick BringToFront (register AD-106).
- Misc.TooltipEnable/Misc.TooltipDelay are client-local UserPreferences
(retail's own 2013 Config tab authors no visible row for either) —
SettingsStore gains a MiscSettings section, no new options-panel row.
- Live-DAT sweep: 434 elements author >=1 trigger property (243 with
literal text this port shows; 191 rely on retail's dynamic
InqProperty(0x49) override, deferred as register TS-85 alongside the
unmodeled P0x3D wrap-width override).
Gates: Release build 0 errors; App suite (live-DAT env) 5410/5407 passed/
3 skipped (was 5379/3); Runtime 1735/0 unchanged; UI.Abstractions 926/0;
full solution 14,617/14,548 passed/69 skipped/0 failed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>