fix(ui): make HiDPI-overflowing containers scrollable — wizard, overlay dialogs, balance recent-tx

At font_scale 1.5 (dpiScale 1.5) three fixed, non-scrolling containers clipped
content off the bottom with no scroll escape:

- First-run wizard: the hand-drawn cards grow ~1.5x past the fixed window,
  pushing Continue / Encrypt & Continue / Skip off-screen (a setup blocker).
  Inject a wheel-driven scroll offset into the layout seed + a scroll indicator;
  gate the wheel on !IsPopupOpen + NoPopupHierarchy so an open combo popup does
  not scroll the wizard behind it. No-op at 1.0x.
- Overlay dialogs (BeginOverlayDialog): auto-height cards taller than the
  viewport (About, Request Payment) ran their footer off the bottom. Add a
  sticky per-open overflow flag that clamps the card to the viewport and makes
  the content child scrollable; short dialogs still center unchanged. Give the
  nested settings clear-history confirm its own idSuffix so it can't inherit the
  parent dialog's overflow state or collide on the child window id.
- Balance Recent Transactions: the dp-scaled address card evicted the recent-tx
  list off the non-scrolling tab host. Cap the card inside RenderSharedAddressList
  against the space that actually remains (minus a caller-provided reserve) so
  the section below stays on-screen — covers all 10 balance layouts.

Verified at font_scale 1.5 across full-node + Lite + Windows (ctest green) and an
adversarial diff review (two low-severity regressions found + fixed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-18 20:12:01 -05:00
parent e24ca015d1
commit 755cf22ad0
6 changed files with 96 additions and 24 deletions

View File

@@ -116,7 +116,7 @@ void RenderCompactHero(App* app, ImDrawList* dl, float availW, float hs, float v
// Render the shared address list section (used by all layouts)
void RenderSharedAddressList(App* app, float listH, float availW,
float glassRound, float hs, float vs) {
float glassRound, float hs, float vs, float reserveBelow) {
using namespace material;
const auto& S = schema::UISchema::instance();
const float dp = Layout::dpiScale();
@@ -225,6 +225,14 @@ void RenderSharedAddressList(App* app, float listH, float availW,
// ---- Glass panel container ----
float addrListH = listH;
// Cap the card to the space that actually remains here (measured AFTER the title + toolbar are laid
// out, so no chrome modelling is needed) minus what the caller reserves for the section below it
// (recent-tx). Without this, a fixed dp-scaled listH grows ~1.5x at high font scale and evicts the
// Recent Transactions list off the bottom of the fixed, non-scrolling tab host.
if (reserveBelow > 0.0f) {
float maxH = ImGui::GetContentRegionAvail().y - reserveBelow;
if (maxH < addrListH) addrListH = maxH;
}
if (addrListH < 40.0f * dp) addrListH = 40.0f * dp;
ImDrawList* dlPanel = ImGui::GetWindowDrawList();