fix(settings): hold the right column with Indent, not a one-shot cursor set

The two-column NODE & SECURITY card collapsed both columns onto the left,
overlapping. A one-time SetCursorScreenPos() can't hold a column: ImGui
resets the cursor X to the window's left indent on every line-advance, so
the first widget in the right column (a Dummy spacer) bounced everything
after it back to the left margin.

Shift the whole right column with ImGui::Indent(colW+gap) instead, so each
line-start lands at the column X; set the first widget's X explicitly to
match, and Unindent before continuing the page. Left column already renders
at the shadowed half-width, so it stays in its lane.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-21 18:04:15 -05:00
parent 77a0ad64b0
commit 3b041f20c1

View File

@@ -1993,6 +1993,11 @@ void RenderSettingsPage(App* app) {
const bool nsTwoCol = nsHasDaemon && contentW > 760.0f * Layout::dpiScale();
const float nsColW = nsTwoCol ? (contentW - nsColGap) * 0.5f : contentW;
const ImVec2 nsColTop = ImGui::GetCursorScreenPos();
// Window-local anchor for the right column. We shift it with Indent() (not a one-shot
// SetCursorScreenPos): ImGui resets the cursor X to the window's left indent on every
// line-advance, so only an indent holds a column across multiple rows/widgets.
const float nsColTopLocalX = ImGui::GetCursorPosX();
const float nsColTopLocalY = ImGui::GetCursorPosY();
{ // ---- left column (Node / RPC / Security) ----
const float contentW = nsColW;
const ImVec2 sectionOrigin(nsColTop.x, nsColTop.y);
@@ -2159,11 +2164,16 @@ void RenderSettingsPage(App* app) {
renderSecuritySection(sectionOrigin.x, contentW, /*includeRpcEncrypt=*/true);
} // ---- end left column ----
const float nsLeftBottom = ImGui::GetCursorScreenPos().y;
if (nsTwoCol) ImGui::SetCursorScreenPos(ImVec2(nsColTop.x + nsColW + nsColGap, nsColTop.y));
if (nsTwoCol) {
// Reset to the top, then indent so every line in the right column starts at the
// column X (the indent persists across line-advances; the explicit SetCursorPosX
// places the very first widget on the same line).
ImGui::SetCursorPosY(nsColTopLocalY);
ImGui::Indent(nsColW + nsColGap);
ImGui::SetCursorPosX(nsColTopLocalX + nsColW + nsColGap);
}
{ // ---- right column (Daemon binary) ----
const float contentW = nsColW;
const ImVec2 sectionOrigin(nsTwoCol ? nsColTop.x + nsColW + nsColGap : nsColTop.x,
nsTwoCol ? nsColTop.y : ImGui::GetCursorScreenPos().y);
// -------------------- DAEMON BINARY --------------------
if (app->supportsFullNodeLifecycleActions()) {
@@ -2315,6 +2325,7 @@ void RenderSettingsPage(App* app) {
}
} // ---- end right column ----
const float nsRightBottom = ImGui::GetCursorScreenPos().y;
if (nsTwoCol) ImGui::Unindent(nsColW + nsColGap); // restore indent before the rest of the page
ImGui::SetCursorScreenPos(ImVec2(nsColTop.x, nsTwoCol ? std::max(nsLeftBottom, nsRightBottom) : nsRightBottom));
ImGui::PopFont();