Summary
When an application takes an org.freedesktop.ScreenSaver inhibit while the
display is already blanked, csd-power powers the display back on. After the
inhibit is released, csd-power does not re-evaluate the current idle time,
so the display is never blanked again for the remainder of that idle period --
even though the X idle counter keeps increasing far beyond the configured
sleep-display-ac timeout.
The result is a monitor that stays on for hours after a single, ~11 second
inhibit. From the user's point of view the "Turn off the screen" setting looks
completely broken, while it actually works correctly the first time.
Environment
- Linux Mint 22.2 (Zara), Cinnamon 6.4.14
- cinnamon-settings-daemon 6.4.3+xia
- X11 session (not Wayland)
- NVIDIA proprietary driver 580.173.02, external DisplayPort monitor,
laptop lid closed
org.cinnamon.settings-daemon.plugins.power sleep-display-ac = 1800
org.cinnamon.desktop.session idle-delay = 600
Observed behaviour
Logged with a script polling XScreenSaverQueryInfo and xset q every 5 s:
19:57:53 idle = 30 min Monitor=On
19:58:03 MONITOR: On -> OFF (idle = 30.2 min) <- correct
20:27:49 idle = 60 min Monitor=OFF
23:46:36 MONITOR: OFF -> On (idle = 258.8 min) <- spontaneous
The wake-up at 23:46:36 happened with no user input at all -- the X idle
counter was at 258.8 minutes and kept increasing across the event.
A parallel dbus-monitor --session "interface='org.freedesktop.ScreenSaver'"
shows the cause, two seconds earlier:
23:46:34 method call interface=org.freedesktop.ScreenSaver; member=Inhibit
string "thunderbird-esr"
string "Playing audio"
23:46:44 method call interface=org.freedesktop.ScreenSaver; member=UnInhibit
After the UnInhibit the display was never blanked again. It was still on the
next morning.
Minimal reproduction
-
Set "Turn off the screen when inactive for" to 1 minute.
-
Leave the machine untouched until the display powers off.
-
Without generating any input, from another machine over SSH (or a script
started beforehand) call:
dbus-send --session --print-reply \
--dest=org.freedesktop.ScreenSaver /ScreenSaver \
org.freedesktop.ScreenSaver.Inhibit string:'test' string:'test'
-> the display powers back on immediately.
-
Release it again with the returned cookie:
dbus-send --session --dest=org.freedesktop.ScreenSaver /ScreenSaver \
org.freedesktop.ScreenSaver.UnInhibit uint32:<cookie>
-
Keep the machine idle. The display never powers off again, although
XScreenSaverQueryInfo reports an idle time far above the configured
timeout.
I verified step 3 locally: with the monitor off and no input, the idle counter
read 192 s, 196 s and 199 s across the Inhibit call while xset q flipped from
Monitor is Off to Monitor is On.
Expected behaviour
When the last inhibitor is released, csd-power should re-evaluate the current
idle time and blank the display immediately if it already exceeds
sleep-display-ac, instead of waiting for an idle alarm that has already fired
and will not fire again until the user generates input.
Additional note
Arguably a screensaver inhibit whose stated reason is audio playback
("Playing audio") should not power a display back on in the first place --
it should at most prevent it from turning off. But the core problem here is the
missing re-arm: without it, any single short inhibit permanently defeats the
display timeout for the rest of the idle period.
Summary
When an application takes an
org.freedesktop.ScreenSaverinhibit while thedisplay is already blanked, csd-power powers the display back on. After the
inhibit is released, csd-power does not re-evaluate the current idle time,
so the display is never blanked again for the remainder of that idle period --
even though the X idle counter keeps increasing far beyond the configured
sleep-display-actimeout.The result is a monitor that stays on for hours after a single, ~11 second
inhibit. From the user's point of view the "Turn off the screen" setting looks
completely broken, while it actually works correctly the first time.
Environment
laptop lid closed
org.cinnamon.settings-daemon.plugins.power sleep-display-ac= 1800org.cinnamon.desktop.session idle-delay= 600Observed behaviour
Logged with a script polling
XScreenSaverQueryInfoandxset qevery 5 s:The wake-up at 23:46:36 happened with no user input at all -- the X idle
counter was at 258.8 minutes and kept increasing across the event.
A parallel
dbus-monitor --session "interface='org.freedesktop.ScreenSaver'"shows the cause, two seconds earlier:
After the
UnInhibitthe display was never blanked again. It was still on thenext morning.
Minimal reproduction
Set "Turn off the screen when inactive for" to 1 minute.
Leave the machine untouched until the display powers off.
Without generating any input, from another machine over SSH (or a script
started beforehand) call:
-> the display powers back on immediately.
Release it again with the returned cookie:
Keep the machine idle. The display never powers off again, although
XScreenSaverQueryInforeports an idle time far above the configuredtimeout.
I verified step 3 locally: with the monitor off and no input, the idle counter
read 192 s, 196 s and 199 s across the Inhibit call while
xset qflipped fromMonitor is OfftoMonitor is On.Expected behaviour
When the last inhibitor is released, csd-power should re-evaluate the current
idle time and blank the display immediately if it already exceeds
sleep-display-ac, instead of waiting for an idle alarm that has already firedand will not fire again until the user generates input.
Additional note
Arguably a screensaver inhibit whose stated reason is audio playback
("Playing audio") should not power a display back on in the first place --
it should at most prevent it from turning off. But the core problem here is the
missing re-arm: without it, any single short inhibit permanently defeats the
display timeout for the rest of the idle period.