fix(ui): wrap chat panel body in outer BeginChild so drag-trap covers it

The InvisibleButton drag-trap inside BeginChild only catches clicks
inside that specific child. Chat had widgets OUTSIDE the inner
##chattail child (the Copy-mode Checkbox + a Separator at top, the
footer Separator + InputTextSubmit at bottom) — empty space around
those widgets fell through directly to the parent window's
window-drag init.

Fix: wrap the entire chat panel body in a single outer ##chatbody
BeginChild before drawing any content. The renderer's drag-trap
fires inside this outer child too, absorbing every empty-space
click in the chat panel body. The inner ##chattail child is now
nested inside it, which doesn't change its scroll-tail semantics
but does mean it gets its own drag-trap as a bonus.

Test fixed: Render_BeginChild_ReservesNegativeFooterFromFrameHeight
was using Single(BeginChild) — there are now two BeginChild calls
(##chatbody outer + ##chattail inner). Switched to Single(... &&
Args[0] == "##chattail") so the test still pins the footer reserve
on the inner call where it lives.

dotnet build green; 1,309 / 1,309 tests green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-26 23:10:01 +02:00
parent 2818fcca8c
commit df9f2fd3da
2 changed files with 24 additions and 2 deletions

View file

@ -67,8 +67,13 @@ public sealed class ChatPanelLayoutTests
panel.Render(new PanelContext(0.016f, new NoBus()), renderer);
var beginChildCall = renderer.Calls.Single(c => c.Method == "BeginChild");
var size = (System.Numerics.Vector2)beginChildCall.Args[1]!;
// L.0 follow-up: the chat panel now wraps its body in an outer
// ##chatbody BeginChild (so empty-space clicks can't drag the
// parent window). The inner ##chattail BeginChild is the one
// that reserves the footer; that's what this test asserts.
var chattailCall = renderer.Calls.Single(c => c.Method == "BeginChild"
&& (string)c.Args[0]! == "##chattail");
var size = (System.Numerics.Vector2)chattailCall.Args[1]!;
// Width 0 = fill available; height < 0 = "fill minus this".
// Reserved height should equal FrameHeightWithSpacing + a small
// separator pad (~6f) so the input never visually clips the