From 10289b33b5bee084f648bfb73db91d7755ca52fa Mon Sep 17 00:00:00 2001 From: DanS Date: Sat, 4 Jul 2026 15:51:57 -0500 Subject: [PATCH] fix(ui): theme-aware modal backdrop + full-window lock overlay Address two GUI-review points: 1. Light themes no longer get a dark modal backdrop: DrawFullWindowBlurBackdrop now tints toward the theme app background (WithAlpha(Background(), ...)) for both the opaque base and the frost, so a light theme gets a light frosted backdrop and a dark theme a dark one. Fixes all blur overlays, not just the lock screen. 2. The lock screen now blurs the WHOLE window (sidebar included), not just the content area: renderLockScreen opens a full-viewport borderless overlay window (##LockOverlay, same pattern as the modal overlays / portfolio, opened from within ##ContentArea) with an input blocker, instead of drawing in the content child. Removed the theme-independent dark scrim (contradicted point 1). Auth logic untouched. Needs GUI re-verify of all auth paths + that the whole screen (incl. sidebar) obscures on lock and unlock returns cleanly. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/app_security.cpp | 31 +++++++++++++++++++++++++------ src/ui/material/draw_helpers.h | 6 ++++-- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/app_security.cpp b/src/app_security.cpp index 4fddf4f..839966f 100644 --- a/src/app_security.cpp +++ b/src/app_security.cpp @@ -767,9 +767,28 @@ void App::checkIdleMining() { void App::renderLockScreen() { using namespace ui::material; + // Full-window lock overlay: cover the ENTIRE viewport (sidebar included) so the whole screen is + // obscured while locked, not just the tab-content area. A borderless, transparent, focused window + // over the main viewport (same pattern as the modal overlays; opened from within ##ContentArea, + // like the portfolio modal). Ended at the bottom of this function. + ImGuiViewport* vp = ImGui::GetMainViewport(); + ImVec2 winPos = vp->Pos, winSize = vp->Size; + ImGui::SetNextWindowPos(winPos); + ImGui::SetNextWindowSize(winSize); + ImGui::SetNextWindowFocus(); + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0)); // transparent — we draw the backdrop + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); + ImGui::Begin("##LockOverlay", nullptr, + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | + ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoSavedSettings); ImDrawList* dl = ImGui::GetWindowDrawList(); - ImVec2 winPos = ImGui::GetWindowPos(); - ImVec2 winSize = ImGui::GetWindowSize(); + // Consume input to everything behind (sidebar included) while locked. + ImGui::SetCursorScreenPos(winPos); + ImGui::InvisibleButton("##LockInputBlocker", winSize, + ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle); // Live-blur backdrop over the wallet content while locked — matches the app's modal look AND // obscures the wallet for privacy (the old backdrop defaulted to 0 = fully visible). Capture-once @@ -793,10 +812,6 @@ void App::renderLockScreen() { cap.captureFrames--; } DrawFullWindowBlurBackdrop(dl, winPos, winMax, /*allowBlur=*/!justLocked); - // A lock screen should read as a clearly-dimmed "locked" state; the blur alone is light in a - // light theme, which washes out the card. Add a theme-independent dark scrim over the blur so - // the card pops in both themes (standard lock-screen dimming). - dl->AddRectFilled(winPos, winMax, IM_COL32(6, 8, 16, 140)); MarkBlurOverlayDrawn(nullptr); // suppress foreground theme-effect bleed + re-capture on unlock } @@ -1068,6 +1083,10 @@ void App::renderLockScreen() { unlockWallet(std::string(lock_passphrase_buf_), timeout); } } + + ImGui::End(); // ##LockOverlay + ImGui::PopStyleVar(3); // WindowRounding, WindowBorderSize, WindowPadding + ImGui::PopStyleColor(); // WindowBg } // =========================================================================== diff --git a/src/ui/material/draw_helpers.h b/src/ui/material/draw_helpers.h index 9325b92..d323d1e 100644 --- a/src/ui/material/draw_helpers.h +++ b/src/ui/material/draw_helpers.h @@ -497,7 +497,9 @@ inline void DrawGlassPanel(ImDrawList* dl, const ImVec2& pMin, inline void DrawFullWindowBlurBackdrop(ImDrawList* dl, const ImVec2& pMin, const ImVec2& pMax, bool allowBlur = true) { - dl->AddRectFilled(pMin, pMax, IM_COL32(9, 10, 16, 255)); // opaque base (shows through if the blur is faint) + // Theme-aware tones: a light theme gets a light frosted backdrop, a dark theme a dark one — the + // backdrop tints toward the app background rather than a hardcoded dark. + dl->AddRectFilled(pMin, pMax, WithAlpha(Background(), 255)); // opaque base (fallback / faint-blur show-through) if (allowBlur && IsBackdropActive() && !dragonx::ui::effects::isLowSpecMode() && effects::ImGuiAcrylic::IsEnabled() && effects::ImGuiAcrylic::IsAvailable()) { // Safe to use a strong custom radius here: while a full-window overlay is active every glass @@ -507,7 +509,7 @@ inline void DrawFullWindowBlurBackdrop(ImDrawList* dl, const ImVec2& pMin, const params.blurRadius = 64.0f; // strong full-window blur params.fallbackColor.w = 1.0f; // full-strength blur so the live content reads effects::ImGuiAcrylic::DrawAcrylicRect(dl, pMin, pMax, params, 0.0f); - dl->AddRectFilled(pMin, pMax, IM_COL32(6, 8, 18, 70)); // slight dim so the card reads as foreground + dl->AddRectFilled(pMin, pMax, WithAlpha(Background(), 70)); // subtle theme-tinted frost so the card reads as foreground } }