fix(CT-GF1): review fix round — literal DrawHere clip shape, empty-clip cull, popup input routing
Applies all 11 items from the Opus dual-lens review of989f6652(0 blockers, 7 SHOULD-FIX, 4 NOTE): - S2: UiElement.DrawSelfAndChildren now pushes the ambient clip right after PushAlpha and wraps OnDraw + the children walk + OnDrawAfterChildren in ONE block — the literal UIRegion::DrawHere @0x0069FA30 shape, which clips an element's OWN DrawSelf too, not just its children (UIElement_Text::DrawSelf @0x00467AA0 locks glyph blits to its own clipped surface rect; UIRegion::DrawSelf @0x0069F1A0 blits per clip rect). Deleted the two now-redundant ad-hoc self-clips this supersedes: UiText.DrawText and UiField.DrawMultiLine both pushed their own (0,0,Width,Height) — exactly what the new ambient clip already provides one level up. Kept UiButton.DrawBlockLabel's clip: it clips to LabelBox/ValueBox, an authored INNER sub-rect that can be smaller than and offset from the button's own full rect — a genuine narrower viewport, not a redundant duplicate. - S3: deleted UiItemList's `ClipsChildren => CellWidth > 0f` override — correct under the old opt-in-false default, inverted under the new default-true (an unconfigured list would stop clipping instead of clipping like everything else). - S4: pinned the escaped-popup input path end to end. New UiAncestorClipTests test mounts a menu inside a short window on a real UiRoot, opens it, and proves a click in the escaped popup region reaches the menu through UiRoot.PopupHit (a plain top-down walk is proven to reject the same point first). UiRoot.WantsMouse now also checks PopupHit — it previously only checked Captured/ HitTestTopDown, so a game action could fire underneath an open dropdown's escaped region. OnMouseDown/OnScroll already routed through PopupHit first (#374); unchanged. - S5: strengthened the Titles-divider regression test's positive half. The old assertion only checked SOME quad's Y fell in a band — vacuously true given other same-band content. Now asserts the divider's exact rect (X and Y), then diffs against the same rect with the divider hidden (Visible=false) to prove the quad was actually attributable to it. - S1: added UiWindowDrawCaptureSweepTests — Character/Chat/Vendor/ Options mounted through their real production Bind entry points with a non-zero sprite resolver, drawn via RecordingGpuDevice, asserting a per-window vertex floor (~40-45% of this session's observed baseline: Character 588, Chat 162, Vendor 54, Options 240) plus one key sprite id read LIVE off the bound controller/element (never hardcoded). Character's key sprite (RetailChromeSprites. TopEdge) specifically exercises OnDrawAfterChildren, the exact path S2's caution note flagged. Inventory/Paperdoll/social/map-house skipped — no single fixture-driven top-level Bind entry point. - S6: added the CT-GF1 subsection to the campaign plan's ledger (989f6652+ this fix round; CT7 re-gate still owed). - S7: UiRenderContext.PushClipUnbounded now resets to the CANVAS rect (0,0,ScreenSize), not null — retail's own popup region is SCREEN-clipped (UIElement_Menu::MakePopup spawns a top-level region bounded by the screen), not truly unbounded. AD-113 amended. - N1: UiRoot overrides ClipsChildren => false — the root's own region IS the screen (the viewport already scissors it), so this is a safety net against a momentarily zero-sized root silently blanking the whole UI tree under the new ancestor-clip default. - N2: added the empty-clip subtree cull (retail's var_24 gate @0x0069FB8E) to DrawSelfAndChildren only — DrawOverlays is a wholly separate traversal untouched by this change. New test proves a menu inside a fully-clipped (zero-width) window still draws its open popup via the overlay pass while the main pass draws nothing. - N3: CT7 script §5 now names the collapsed-toolbar check and the four highest-overflow windows (combat/vitals bar, Options bottom-button row, map/house page, floaty chat) as explicit eyeball items for the re-gate. - N4: verification below covers both the working tree and the clean committed tree. Decomp anchors: UIRegion::DrawHere @0x0069FA30 (var_24 gate @0x0069FB8E); UIElement_Text::DrawSelf @0x00467AA0 (self-clip); UIRegion::DrawSelf @0x0069F1A0; UIElement_Menu::MakePopup (screen- clipped popup region). Verification (both runs green, --filter "Lane!=InstalledDat& Lane!=PreparedPackage&Lane!=Live&Lane!=Manual&Lane!=Timing& Lane!=Windows&Lane!=Linux&Lane!=SystemFont&Purpose!=Diagnostic& Status!=KnownFailure"): full Release solution build green; working tree 14,900+ tests across every project (one LandblockPresentation PipelineTests flake reproduced ONLY under full-solution parallel load, passes standalone and on rerun — unrelated to this change, streaming domain); InstalledDat lane green (ACDREAM_RUN_INSTALLED_DAT _TESTS=1, Status!=KnownFailure, 205+34+3+172 App/Content/Bake/Core tests). Clean committed tree (git stash push -u the uncommitted owner probe + docs files, rerun, stash pop) reported in the session summary. src/AcDream.App/UI/UiRoot.cs carries an unrelated, pre-existing uncommitted owner probe (ACDREAM_PROBE_UI_HOVER) — staged selectively (git add -p) so only this commit's own two hunks (ClipsChildren override, WantsMouse) landed; the probe hunk is untouched and stays uncommitted, same as before this fix round. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
989f665214
commit
025108a8aa
13 changed files with 717 additions and 120 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# Campaign CT — Character-panel retail parity (header identity, Titles page, resize/scrollbar, row alignment)
|
||||
|
||||
**Status:** IMPLEMENTATION COMPLETE 2026-08-25 — CT1-CT6 all review-closed (per-slice Opus dual-lens review + fix round); CT7 connected gate script ready at `docs/research/2026-08-25-campaign-ct-test-script.md`, awaiting the owner's drive. NOT pushed to gitea (owner directive).
|
||||
**Status:** IMPLEMENTATION COMPLETE 2026-08-25 — CT1-CT6 all review-closed (per-slice Opus dual-lens review + fix round). CT-GF1 (the CT7 gate's own first finding — the client-wide retained-UI ancestor clip) landed `989f6652` and its fix round is CODE-COMPLETE (see the CT-GF1 subsection below); CT7 connected gate script ready at `docs/research/2026-08-25-campaign-ct-test-script.md`, still awaiting the owner's drive. NOT pushed to gitea (owner directive).
|
||||
**Execution model:** Fable plans and coordinates; Sonnet implements each
|
||||
slice; Opus runs the dual-lens review (retail-faithful + architectural)
|
||||
per slice, then a fix round. No pushes to gitea until the owner says so.
|
||||
|
|
@ -547,6 +547,47 @@ cited (`0x10000180`, 300×362), not a new number.
|
|||
titles round trip against ACE (earn/set/display), header lines vs
|
||||
retail side-by-side, resize behavior, row alignment screenshots.
|
||||
|
||||
### CT-GF1 — client-wide retained-UI ancestor clip (gate finding + fix round)
|
||||
|
||||
Landed `989f6652`: ports retail's `UIRegion::DrawHere @0x0069FA30`
|
||||
ancestor-clip intersection as `UiElement.ClipsChildren`'s new client-wide
|
||||
default (true), fixing the CT7 gate's own first finding — the Titles page's
|
||||
authored divider `0x10000530` escaping the Character window above its top
|
||||
edge at the CT6-correct 372px mounted default. One opt-out
|
||||
(`UiElement.ExpandsClipForPopup`, `UiMenu`'s inline-drawn popup) plus new
|
||||
`UiAncestorClipTests` mechanism coverage.
|
||||
|
||||
**Fix round** (Opus dual-lens review, 0 blockers / 7 SHOULD-FIX / 4 NOTE, all
|
||||
applied): moved the ambient clip to wrap `OnDraw` + children +
|
||||
`OnDrawAfterChildren` in one block — the literal `DrawHere` shape, clipping
|
||||
an element's own `DrawSelf` too, not just its children (`UIElement_Text::
|
||||
DrawSelf @0x00467AA0`; `UIRegion::DrawSelf @0x0069F1A0`) — and deleted the
|
||||
two now-redundant ad-hoc self-clips it superseded (`UiText.DrawText`,
|
||||
`UiField.DrawMultiLine`); kept the one that clips to a genuinely smaller
|
||||
authored inner rect (`UiButton.DrawBlockLabel`'s `LabelBox`/`ValueBox`).
|
||||
Deleted `UiItemList`'s `ClipsChildren` override (inverted under the new
|
||||
default). Pinned the escaped-popup input path end to end (`UiRoot.PopupHit`
|
||||
routing, `WantsMouse`) with a new real-`UiRoot` test. Strengthened the
|
||||
Titles-divider regression test's positive half (exact-rect assertion +
|
||||
visible/hidden diff, not a bare Y-band check). Added a draw-capture
|
||||
regression sweep across Character/Chat/Vendor/Options mounted through their
|
||||
real controllers (`UiWindowDrawCaptureSweepTests`). `PushClipUnbounded` now
|
||||
resets to the screen rect, not `null` — retail's own popup region is
|
||||
screen-clipped, not truly unbounded (AD-113 amended). `UiRoot.ClipsChildren`
|
||||
now explicitly overrides false (the root's own region IS the screen — a
|
||||
safety net against a momentarily zero-sized root blanking the whole UI).
|
||||
Added the empty-clip subtree cull (retail's `var_24` gate), scoped to the
|
||||
main draw pass only — the popup's separate `DrawOverlays` traversal is
|
||||
provably unaffected (new coverage: a menu inside a fully-clipped window
|
||||
still draws its popup).
|
||||
|
||||
**Owed:** the CT7 re-gate (script `docs/research/2026-08-25-campaign-ct-test-
|
||||
script.md`) still needs the owner's connected drive — this fix round landed
|
||||
on the automated side only. §5 of that script now also names the
|
||||
collapsed-toolbar check and the four highest-overflow windows (combat/
|
||||
vitals bar, Options bottom-button row, map/house page, floaty chat) as
|
||||
explicit eyeball items for that same re-gate.
|
||||
|
||||
## Review protocol
|
||||
|
||||
Per slice: Sonnet implements → Opus dual-lens review (lens 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue