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:
parent
2818fcca8c
commit
df9f2fd3da
2 changed files with 24 additions and 2 deletions
|
|
@ -90,6 +90,20 @@ public sealed class ChatPanel : IPanel
|
|||
return;
|
||||
}
|
||||
|
||||
// L.0 follow-up: wrap the entire chat panel body in a single
|
||||
// outer BeginChild so empty-space clicks anywhere in the body
|
||||
// (Checkbox row, between Separator and input, etc.) are
|
||||
// absorbed by BeginChild's drag-trap (an InvisibleButton the
|
||||
// ImGui renderer adds inside every BeginChild). Without this
|
||||
// wrapper the chat panel was draggable from any empty body
|
||||
// pixel — only the inner ##chattail area was protected.
|
||||
if (!renderer.BeginChild("##chatbody", new System.Numerics.Vector2(0f, 0f)))
|
||||
{
|
||||
renderer.EndChild();
|
||||
renderer.End();
|
||||
return;
|
||||
}
|
||||
|
||||
// L.0 follow-up: top-of-panel "Copy mode" toggle. When on, the
|
||||
// chat tail rendering swaps to TextMultilineReadOnly so the
|
||||
// user can mark + Ctrl+C any text. Off (default) preserves the
|
||||
|
|
@ -186,6 +200,7 @@ public sealed class ChatPanel : IPanel
|
|||
if (TryHandleClientCommand(trimmed))
|
||||
{
|
||||
_input = string.Empty;
|
||||
renderer.EndChild(); // outer ##chatbody
|
||||
renderer.End();
|
||||
return;
|
||||
}
|
||||
|
|
@ -206,6 +221,7 @@ public sealed class ChatPanel : IPanel
|
|||
_vm.ShowSystemMessage(
|
||||
$"Unknown command: {verb}. Type /help for the list of supported commands.");
|
||||
_input = string.Empty;
|
||||
renderer.EndChild(); // outer ##chatbody
|
||||
renderer.End();
|
||||
return;
|
||||
}
|
||||
|
|
@ -225,6 +241,7 @@ public sealed class ChatPanel : IPanel
|
|||
_input = string.Empty;
|
||||
}
|
||||
|
||||
renderer.EndChild(); // outer ##chatbody
|
||||
renderer.End();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue