Fix screen flash when waking from sleep into the unlock screen
The lock service arms a 5s blank timer whenever the screen locks, and input at the lock screen re-arms it. Closing the lid sprays pointer noise over the lock surface, so the timer was routinely armed right before suspend, froze mid-countdown, and fired moments after resume -- blanking the freshly woken unlock screen under the user. Guard the timer with a wall-clock check: if far more time elapsed than the interval, the countdown slept through a suspend, so take a fresh run-up instead of blanking. This also blanks the lock screen 5s after an untouched resume. Two accomplices made the flash worse and hid the real bug: - The clamshell watcher's 2s poll fired an unconditional global DPMS enable whenever no external monitor was active, relighting any blank within 2 seconds (lock-screen blanking never stuck on undocked laptops) and racing the resume modeset. Recovery now only wakes displays when it actually re-enables one. - Every keystroke at the lock screen dispatched a redundant DPMS enable via omarchy-system-wake, forcing extra modesets in the fragile just-resumed DRM state. Brightness "on" now skips the dispatch when every active display is already lit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
324fd387c0
commit
54d79d9d16
@@ -32,6 +32,10 @@ if [[ $step == "off" ]]; then
|
|||||||
hyprctl dispatch 'hl.dsp.dpms({ action = "disable" })' >/dev/null 2>&1
|
hyprctl dispatch 'hl.dsp.dpms({ action = "disable" })' >/dev/null 2>&1
|
||||||
exit 0
|
exit 0
|
||||||
elif [[ $step == "on" ]]; then
|
elif [[ $step == "on" ]]; then
|
||||||
|
# Skip the dispatch when every active display is already lit: a redundant
|
||||||
|
# DPMS enable right after system resume forces another modeset, which blanks
|
||||||
|
# the panel for a beat (visible flash at the unlock screen).
|
||||||
|
hyprctl monitors -j 2>/dev/null | jq -e '[.[] | select(.disabled == false)] | length > 0 and all(.dpmsStatus)' >/dev/null 2>&1 && exit 0
|
||||||
hyprctl dispatch 'hl.dsp.dpms({ action = "enable" })' >/dev/null 2>&1
|
hyprctl dispatch 'hl.dsp.dpms({ action = "enable" })' >/dev/null 2>&1
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -42,13 +42,14 @@ off() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
recover() {
|
recover() {
|
||||||
if ! omarchy-hyprland-monitor-external-active; then
|
# Runs from the clamshell watcher every few seconds, so it must be a no-op
|
||||||
if omarchy-hyprland-toggle-enabled $TOGGLE; then
|
# unless it actually re-enables a display: an unconditional wake here undoes
|
||||||
omarchy-hyprland-toggle $TOGGLE off
|
# lock-screen blanking and races the resume modeset into a visible flash.
|
||||||
fi
|
omarchy-hyprland-monitor-external-active && return 0
|
||||||
|
omarchy-hyprland-toggle-enabled $TOGGLE || return 0
|
||||||
|
|
||||||
wake
|
omarchy-hyprland-toggle $TOGGLE off
|
||||||
fi
|
wake
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle() {
|
toggle() {
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ Item {
|
|||||||
|
|
||||||
resetAuthenticationState()
|
resetAuthenticationState()
|
||||||
lockRequested = true
|
lockRequested = true
|
||||||
idleBlankTimer.restart()
|
armBlankTimer()
|
||||||
logEvent("lock-requested")
|
logEvent("lock-requested")
|
||||||
queueSessionLock()
|
queueSessionLock()
|
||||||
|
|
||||||
@@ -134,9 +134,14 @@ Item {
|
|||||||
runWake()
|
runWake()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function armBlankTimer() {
|
||||||
|
idleBlankTimer.armedAt = Date.now()
|
||||||
|
idleBlankTimer.restart()
|
||||||
|
}
|
||||||
|
|
||||||
function runWake() {
|
function runWake() {
|
||||||
if (!wakeProcess.running) wakeProcess.running = true
|
if (!wakeProcess.running) wakeProcess.running = true
|
||||||
if (lockRequested) idleBlankTimer.restart()
|
if (lockRequested) armBlankTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
function runBlank() {
|
function runBlank() {
|
||||||
@@ -370,7 +375,17 @@ Item {
|
|||||||
id: idleBlankTimer
|
id: idleBlankTimer
|
||||||
interval: 5000
|
interval: 5000
|
||||||
repeat: false
|
repeat: false
|
||||||
onTriggered: if (root.lockRequested && !root.authenticating) root.runBlank()
|
property double armedAt: 0
|
||||||
|
onTriggered: {
|
||||||
|
// A countdown frozen by suspend fires right after resume, which would
|
||||||
|
// blank the freshly woken unlock screen under the user. Wall-clock time
|
||||||
|
// exposes the gap: take a fresh run-up instead of blanking.
|
||||||
|
if (Date.now() - armedAt > interval + 2000) {
|
||||||
|
root.armBlankTimer()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (root.lockRequested && !root.authenticating) root.runBlank()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
@@ -395,7 +410,7 @@ Item {
|
|||||||
onAuthenticatingChanged: {
|
onAuthenticatingChanged: {
|
||||||
if (!lockRequested) return
|
if (!lockRequested) return
|
||||||
if (authenticating) idleBlankTimer.stop()
|
if (authenticating) idleBlankTimer.stop()
|
||||||
else idleBlankTimer.restart()
|
else armBlankTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
FileView {
|
FileView {
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ grep -F "hyprctl dispatch 'hl.dsp.dpms({ action = \"enable\" })' >/dev/null 2>&1
|
|||||||
grep -F 'hyprctl monitors all -j' "$monitor_internal" >/dev/null
|
grep -F 'hyprctl monitors all -j' "$monitor_internal" >/dev/null
|
||||||
grep -F 'omarchy-hyprland-monitor-external-active' "$monitor_internal" >/dev/null
|
grep -F 'omarchy-hyprland-monitor-external-active' "$monitor_internal" >/dev/null
|
||||||
grep -F 'wake' "$monitor_internal" >/dev/null
|
grep -F 'wake' "$monitor_internal" >/dev/null
|
||||||
|
grep -F 'omarchy-hyprland-toggle-enabled $TOGGLE || return 0' "$monitor_internal" >/dev/null
|
||||||
pass "internal monitor helper can re-enable disabled laptop displays"
|
pass "internal monitor helper can re-enable disabled laptop displays"
|
||||||
|
pass "internal monitor recovery only wakes displays when it re-enables one"
|
||||||
|
|
||||||
grep -F 'omarchy-hyprland-monitor-external-active' "$monitor_mirror" >/dev/null
|
grep -F 'omarchy-hyprland-monitor-external-active' "$monitor_mirror" >/dev/null
|
||||||
pass "internal mirror helper recovers when no active external display remains"
|
pass "internal mirror helper recovers when no active external display remains"
|
||||||
|
|||||||
Reference in New Issue
Block a user