feat(security): live-blur backdrop for the lock screen (Phase 4)
The security DIALOGS (encrypt/decrypt/change-passphrase/remove-encryption, PIN set/change/remove) already adopted the blur backdrop via the Phase 2 flip (they use BeginOverlayDialog). This finishes Phase 4 by giving the bespoke lock screen the same live-blur backdrop over the wallet content — restyle only, auth logic (PIN/passphrase input, attempt counting, lockout timer) untouched. The lock screen previously defaulted to backdrop-alpha=0 (wallet fully visible behind the card); the blur now obscures it — a privacy improvement as well as a consistency one. Capture-once on lock-open + resize (frame-gap detected via the shared BlurCaptureStateFor), MarkBlurOverlayDrawn drives the theme-effect suppression + acrylic re-capture on unlock. The opaque base in DrawFullWindowBlurBackdrop guarantees the wallet is obscured even if blur is unavailable (low-spec / acrylic-off / capture failure) — no content leak. UV mapping is screen-space, so the content-area sub-rect blurs the correct region. Needs GUI verification of every auth path (PIN/passphrase unlock, lockout). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -771,11 +771,29 @@ void App::renderLockScreen() {
|
|||||||
ImVec2 winPos = ImGui::GetWindowPos();
|
ImVec2 winPos = ImGui::GetWindowPos();
|
||||||
ImVec2 winSize = ImGui::GetWindowSize();
|
ImVec2 winSize = ImGui::GetWindowSize();
|
||||||
|
|
||||||
// Optional backdrop (0 = no darkening)
|
// Live-blur backdrop over the wallet content while locked — matches the app's modal look AND
|
||||||
float backdropAlpha = ui::schema::UI().drawElement("screens.lock-screen", "backdrop-alpha").opacity;
|
// obscures the wallet for privacy (the old backdrop defaulted to 0 = fully visible). Capture-once
|
||||||
if (backdropAlpha > 0.0f) {
|
// on lock-open + resize; the opaque base inside DrawFullWindowBlurBackdrop guarantees the wallet
|
||||||
ImU32 backdropCol = IM_COL32(0, 0, 0, (int)(255 * backdropAlpha));
|
// is obscured even when the blur is unavailable (low-spec / acrylic-off / first frame / capture
|
||||||
dl->AddRectFilled(winPos, ImVec2(winPos.x + winSize.x, winPos.y + winSize.y), backdropCol);
|
// 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
|
// Card
|
||||||
|
|||||||
Reference in New Issue
Block a user