diff --git a/surfaces/quickshell/modules/common/panels/lock/LockScreen.qml b/surfaces/quickshell/modules/common/panels/lock/LockScreen.qml index 20e9c0c..91e9434 100644 --- a/surfaces/quickshell/modules/common/panels/lock/LockScreen.qml +++ b/surfaces/quickshell/modules/common/panels/lock/LockScreen.qml @@ -121,12 +121,23 @@ Scope { onSecureChanged: { GlobalStates.screenLockSecure = secure; console.log("[lock] session lock secure=" + secure); - if (secure && !root.bootDismissed) { - root.bootDismissed = true; - GlobalStates.bootBloomActive = false; - } + root.dismissBloomIfSecure(); } + // The dismissal above is an EDGE, and a scene reload is exactly the + // case where the edge is in the past. `GlobalStates.bootBloomActive` + // defaults to true on every scene construction and `bootDismissed` + // resets with it, but a reload during an already-secure lock never + // moves `secure` — so nothing ever cleared the bloom and the phone sat + // under a full-screen white overlay until the shell was restarted. + // Observed 2026-07-29: a reload at 10:44:10 with no secure transition + // after it, and a solid white `grim` capture. + // + // Same shape as the locked_ack edge that never re-fired after a + // sessiond restart, and as the ChargeRate stale-scene reload. Check the + // LEVEL at construction as well as the edge. + Component.onCompleted: root.dismissBloomIfSecure() + // The compositor can end our lock without us asking: ext-session-lock // `finished` (denied because another client held it) makes quickshell // drop `locked` to false C++-side. Our request bool never hears about @@ -144,6 +155,17 @@ Scope { } } + // Idempotent, and deliberately NOT a timeout. A bloom that outlives its + // reason is a bug to locate, not something to paper over with a timer — if + // this is still up while the lock is secure, the caller is missing and the + // fix belongs where the call is missing. + function dismissBloomIfSecure() { + if (!lock.secure || root.bootDismissed) + return; + root.bootDismissed = true; + GlobalStates.bootBloomActive = false; + } + function lock() { if (Config.options.lock.useHyprlock) { Quickshell.execDetached(["bash", "-c", "pidof hyprlock || hyprlock"]);