Skip to content

Turn off screen during system sleep - #2480

Open
nfraprado wants to merge 1 commit into
ValveSoftware:masterfrom
nfraprado:dbus-prepare-for-sleep-display-off
Open

nfraprado wants to merge 1 commit into
ValveSoftware:masterfrom
nfraprado:dbus-prepare-for-sleep-display-off

Conversation

@nfraprado

Copy link
Copy Markdown

Hook into the PrepareForSleep D-Bus signal from logind and trigger screen sleep before the system goes to sleep. This improves the user experience when the system goes into hibernation, since currently during the time window between when userspace threads get frozen and the display driver in the kernel gets suspended, which can take a few seconds, the last image on the screen stays frozen. Furthermore, on some platforms like the Steam Machine, during this time window the last second of audio also gets repeated in a loop. By turning off the display early in the hibernation process, we avoid both issues and give a smoother experience to the user. This also mimicks the behavior from KDE plasma.

In order to achieve this:

  • Extend the backend interface to expose screen sleep functionality (which is currently only supported by the DRM backend) and make the new code a no-op when the backend doesn't support it.
  • Spawn a new thread and rely on libsystemd to listen for the PrepareForSleep signal from logind and turn the display off/on in response, and take an inhibitor lock to delay system sleep until the screen has been turned off.

The introduced dependency on libsystemd is optional and in practice is not new: the only backend that currently supports screen sleep is DRM, and it already requires libsystemd indirectly, since it requires the libinput backend in wlroots, which requires libseat, which in turn requires libsystemd.

@oSoMoN oSoMoN left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"dbus.cpp" is a very generic name that suggests it contains general dbus scaffolding code, can it be renamed to reflect its specific purpose?

In the future we may need to factor out some common D-Bus helpers, and I can imagine that they would go into a dbus.{h,cpp} pair of files.

Comment thread src/dbus.cpp Outdated
Comment thread src/main.cpp Outdated
Comment thread src/dbus.cpp Outdated
Comment thread src/Backends/DeferredBackend.h
Comment thread src/dbus.cpp Outdated
Comment thread src/dbus.cpp Outdated
Comment thread src/backend.h
Comment thread src/dbus.cpp Outdated
Comment thread src/dbus.cpp Outdated
@nfraprado
nfraprado force-pushed the dbus-prepare-for-sleep-display-off branch from c3b38b0 to a912dc3 Compare October 16, 2026 15:10
Comment thread src/steamcompmgr.cpp Outdated
Comment thread src/steamcompmgr.cpp Outdated
Comment thread src/Backends/DeferredBackend.h
Comment thread src/wlserver.cpp Outdated
Comment thread src/logind_sleep.cpp Outdated
Comment thread src/logind_sleep.cpp Outdated
@nfraprado
nfraprado force-pushed the dbus-prepare-for-sleep-display-off branch from a912dc3 to 9db305b Compare October 21, 2026 19:20
@nfraprado

Copy link
Copy Markdown
Author

Thank you for the feedback. I've addressed all the feedback from this second pass, and also did a few other tweaks while at it.

@oSoMoN oSoMoN left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Just a couple of minor suggestions inline, and this will be good to merge.

Comment thread src/backend.h Outdated
Comment thread src/Backends/DRMBackend.cpp Outdated
Hook into the PrepareForSleep D-Bus signal from logind and trigger
screen sleep before the system goes to sleep. This improves the user
experience when the system goes into hibernation, since currently
during the time window between when userspace threads get frozen and the
display driver in the kernel gets suspended, which can take a few
seconds, the last image on the screen stays frozen. Furthermore, on some
platforms like the Steam Machine, during this time window the last
second of audio also gets repeated in a loop. By turning off the display
early in the hibernation process, we avoid both issues and give a
smoother experience to the user. This also mimics the behavior from KDE
plasma.

In order to achieve this:

* Extend the backend interface to expose screen sleep functionality
  (which is currently only supported by the DRM backend) and make the
  new code a no-op when the backend doesn't support it.
* Spawn a new thread and rely on libsystemd to listen for the
  PrepareForSleep signal from logind and turn the display off/on in
  response, and take an inhibitor lock to delay system sleep until the
  screen has been turned off.
* In the DRM backend, make the atomic commit blocking for screen sleep
  operations and update the sleep status after commit to allow callers
  to wait for the sleep to actually be applied on hardware.

The introduced dependency on libsystemd is optional and in practice is
not new: the only backend that currently supports screen sleep is DRM,
and it already requires libsystemd indirectly, since it requires the
libinput backend in wlroots, which requires libseat, which in turn
requires libsystemd.

Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
@nfraprado
nfraprado force-pushed the dbus-prepare-for-sleep-display-off branch from 9db305b to 3c9e30c Compare October 27, 2026 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants