fix(ui): frost the chat + contacts panes with acrylic blur + padding

The chat and contacts panes drew flat ImGui fills (ChildBg / default
WindowBg / NoBackground), so they never sampled the acrylic blur and
showed the raw backdrop texture. Route them through DrawGlassPanel --
the pattern the peers_tab sibling and every other tab already use:

- chat: frost the conversation-list + thread panes and the composer
  input box, and add inner padding so content doesn't hug the glass edges
- contacts: frost the card/list container AND the table view, padding both

Padding needed ImGuiChildFlags_AlwaysUseWindowPadding -- a borderless
child silently ignores WindowPadding otherwise (documented gotcha in
daemon_download_dialog.h). BeginTable can't take that flag, so the table
view is inset within its glass panel instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-19 19:32:11 -05:00
co-authored by Claude Opus 4.8
parent 40f8425d94
commit 38f2aa2f8f
2 changed files with 77 additions and 10 deletions
+29 -2
View File
@@ -1005,9 +1005,23 @@ void RenderContactsTab(App* app)
if (viewMode == 2) {
// ── TABLE mode (material-ized): no outer/grid borders, row backgrounds, interactive sort. ──
// Frosted-glass panel behind the table so it blurs the backdrop like the card/list view (the
// table's translucent row backgrounds let the blur show through). A BeginTable can't take
// AlwaysUseWindowPadding, so inset the table itself inside the glass so its headers/cells
// don't hug the container edges.
ImDrawList* tpdl = ImGui::GetWindowDrawList();
const ImVec2 tpMin = ImGui::GetCursorScreenPos();
const float tpW = ImGui::GetContentRegionAvail().x;
const float tIpad = 12.0f * dp, tVpad = 10.0f * dp;
{
material::GlassPanelSpec g; g.rounding = 12.0f * dp; g.fillAlpha = 14; g.borderAlpha = 34;
material::DrawGlassPanel(tpdl, tpMin, ImVec2(tpMin.x + tpW, tpMin.y + listH), g);
}
ImGui::SetCursorScreenPos(ImVec2(tpMin.x + tIpad, tpMin.y + tVpad));
if (ImGui::BeginTable("AddressBookTable", 3,
ImGuiTableFlags_RowBg | ImGuiTableFlags_Sortable |
ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY, ImVec2(0, listH)))
ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY,
ImVec2(tpW - 2.0f * tIpad, listH - 2.0f * tVpad)))
{
ImGui::TableSetupColumn(TR("label"), ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_DefaultSort, 1.5f);
ImGui::TableSetupColumn(TR("address_label"), ImGuiTableColumnFlags_WidthStretch, 2.6f);
@@ -1093,8 +1107,20 @@ void RenderContactsTab(App* app)
return toLower(entries[a].label).compare(toLower(entries[b].label)) < 0;
});
}
// Frosted-glass list container so the contacts area blurs the backdrop (peers_tab pattern:
// glass behind a NoBackground list child) instead of showing the raw texture through the pane.
{
ImDrawList* pdl = ImGui::GetWindowDrawList();
const ImVec2 pMin = ImGui::GetCursorScreenPos();
const float pW = ImGui::GetContentRegionAvail().x;
material::GlassPanelSpec g; g.rounding = 12.0f * dp; g.fillAlpha = 14; g.borderAlpha = 34;
material::DrawGlassPanel(pdl, pMin, ImVec2(pMin.x + pW, pMin.y + listH), g);
}
// AlwaysUseWindowPadding: a borderless child ignores WindowPadding without it, so the rows
// would hug the frosted container's edges.
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(12.0f * dp, 10.0f * dp));
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0,0,0,0));
ImGui::BeginChild("##contactList", ImVec2(0, listH), false,
ImGui::BeginChild("##contactList", ImVec2(0, listH), ImGuiChildFlags_AlwaysUseWindowPadding,
ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoScrollWithMouse);
material::ApplySmoothScroll(); // wheel-lerp scroll, matching the rest of the app
if (visibleRows.empty()) {
@@ -1243,6 +1269,7 @@ void RenderContactsTab(App* app)
}
ImGui::EndChild();
ImGui::PopStyleColor();
ImGui::PopStyleVar(); // ##contactList inner WindowPadding
}
// Shared right-click context menu (opened by either view's row right-click; acts on the selection).