diff --git a/src/app_security.cpp b/src/app_security.cpp index 04d4976..aa8a8ee 100644 --- a/src/app_security.cpp +++ b/src/app_security.cpp @@ -771,11 +771,29 @@ void App::renderLockScreen() { ImVec2 winPos = ImGui::GetWindowPos(); ImVec2 winSize = ImGui::GetWindowSize(); - // Optional backdrop (0 = no darkening) - float backdropAlpha = ui::schema::UI().drawElement("screens.lock-screen", "backdrop-alpha").opacity; - if (backdropAlpha > 0.0f) { - ImU32 backdropCol = IM_COL32(0, 0, 0, (int)(255 * backdropAlpha)); - dl->AddRectFilled(winPos, ImVec2(winPos.x + winSize.x, winPos.y + winSize.y), backdropCol); + // 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 + // on lock-open + resize; the opaque base inside DrawFullWindowBlurBackdrop guarantees the wallet + // is obscured even when the blur is unavailable (low-spec / acrylic-off / first frame / capture + // failure), so this can't leak content. Purely visual — the auth logic below is untouched. + ImVec2 winMax(winPos.x + winSize.x, winPos.y + winSize.y); + { + BlurCaptureState& cap = BlurCaptureStateFor("##LockScreen"); + int frame = ImGui::GetFrameCount(); + bool justLocked = (cap.lastSeenFrame < frame - 1); + cap.lastSeenFrame = frame; + if (justLocked || cap.w != winSize.x || cap.h != winSize.y) cap.captureFrames = 3; + cap.w = winSize.x; cap.h = winSize.y; + CapturingBlurBackdropRef() = (cap.captureFrames > 0); + if (cap.captureFrames > 0) { + if (ImDrawCallback liveCap = ui::effects::ImGuiAcrylic::GetLiveCaptureCallback()) { + dl->AddCallback(liveCap, nullptr); + dl->AddCallback(ImDrawCallback_ResetRenderState, nullptr); + } + cap.captureFrames--; + } + DrawFullWindowBlurBackdrop(dl, winPos, winMax, /*allowBlur=*/!justLocked); + MarkBlurOverlayDrawn(nullptr); // suppress foreground theme-effect bleed + re-capture on unlock } // Card