From 3839d0b4e0054c292d93ce143f39d91dce88f1dd Mon Sep 17 00:00:00 2001 From: Omarchybot <317366263+omarchybot@users.noreply.github.com> Date: Thu, 1 Oct 2026 11:45:45 +0200 Subject: [PATCH] Keep a pending idle action on its deadline when the timings change With 0 meaning off, setting the screensaver to 0 while the screensaver is up moves the first idle deadline to the lock's, which turns the pending lock's bound interval to 0 and locks at once, minutes early. Set each timer's interval when the cycle starts, so a change to shell.json takes effect from the next cycle. Co-Authored-By: Claude Opus 5.5 Co-Authored-By: Codex Medium --- shell/plugins/services/idle/Service.qml | 14 ++++++++++---- test/shell.d/idle-test.sh | 10 ++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/shell/plugins/services/idle/Service.qml b/shell/plugins/services/idle/Service.qml index 9321150d..860a3b23 100644 --- a/shell/plugins/services/idle/Service.qml +++ b/shell/plugins/services/idle/Service.qml @@ -94,14 +94,22 @@ Item { root.screensaverStartedThisCycle = false resetScreensaverWindows() + // Set this cycle's deadlines once: a bound interval would restart a pending + // timer from the moment shell.json changes, locking early or late. if (root.screensaverEnabled) { if (root.screensaverDelaySeconds === 0) launchScreensaver() - else screensaverTimer.restart() + else { + screensaverTimer.interval = root.screensaverDelaySeconds * 1000 + screensaverTimer.restart() + } } if (root.lockEnabled) { if (root.lockDelaySeconds === 0) lockSystem("lock-timeout-immediate") - else lockTimer.restart() + else { + lockTimer.interval = root.lockDelaySeconds * 1000 + lockTimer.restart() + } } } @@ -265,14 +273,12 @@ Item { Timer { id: screensaverTimer - interval: root.screensaverDelaySeconds * 1000 repeat: false onTriggered: if (root.screensaverEnabled) root.launchScreensaver() } Timer { id: lockTimer - interval: root.lockDelaySeconds * 1000 repeat: false onTriggered: if (root.idleEnabled && root.idledThisCycle && root.lockEnabled) root.lockSystem("lock-timeout") } diff --git a/test/shell.d/idle-test.sh b/test/shell.d/idle-test.sh index d5bd7afa..a5057a26 100644 --- a/test/shell.d/idle-test.sh +++ b/test/shell.d/idle-test.sh @@ -41,6 +41,16 @@ assert( /id: lockTimer[\s\S]*?onTriggered: if \([^)]*root\.lockEnabled\) root\.lockSystem\("lock-timeout"\)/.test(serviceSource), 'idle does not fire a pending lock once its timeout is set to 0' ) +assert( + /lockTimer\.interval = root\.lockDelaySeconds \* 1000\s*\n\s*lockTimer\.restart\(\)/.test(serviceSource) && + !/interval: root\.lockDelaySeconds/.test(serviceSource), + 'idle keeps a pending lock on its deadline when shell.json changes mid-cycle' +) +assert( + /screensaverTimer\.interval = root\.screensaverDelaySeconds \* 1000\s*\n\s*screensaverTimer\.restart\(\)/.test(serviceSource) && + !/interval: root\.screensaverDelaySeconds/.test(serviceSource), + 'idle keeps a pending screensaver on its deadline when shell.json changes mid-cycle' +) assertDeepEqual(idle.eventParts({ data: 'a,b,c' }, 2), ['a', 'b', 'c'], 'idle parses raw event data') assertDeepEqual(