Subject: bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake

From: Andrew Cohen <[email-masked]>
Date: Fri, 07 Feb 2025 15:14:05 +0800

>>>>> "AC" == Andrew Cohen <[email-masked]> writes:

>>>>> "SM" == Stefan Monnier <[email-masked]> writes:
    AC> [...]

    SM> so what do we know about when we'll sleep?  Can we influence
    SM> (e.g. delay) it?

    AC> So I can make it work easily for the D-Bus backend, with one
    AC> minor issue.  The D-Bus interface returns a file descriptor (a
    AC> natural number) for the FIFO that is inhibiting sleep. To allow
    AC> sleep I have to close this. How can I do that from Emacs?

Just an update:

I have a more or less complete implementation using Michael's
modifications for `insert-special-event'.  A sleep-event triggers a
function that manages blocking/unblocking sleep and running the
appropriate hooks. This will work on any system that generates the
sleep-event (the blocking/unblocking routines are D-Bus specific, but
once we know what this looks like on other systems we can dispatch
appropriately).  The D-Bus handler just inserts a synthetic sleep-event
when it receives a PrepareForSleep notification. This is what I have
been running for today with no problems.

I spent some time looking over the documentation and the general
recommendations for dealing with sleep notifications. The recommendation
(from systemd/logind) is that any application that needs to do something
prior to sleep should monitor for sleep notifications and install the
block preventing sleep at the time that monitoring starts. When a
notification of sleep is received the application should complete its
work and then remove the block. After waking up, the block should be
restored.  This is the logic that I have implemented. (systemd allows me
to list all of the applications holding blocks. My gnome desktop
typically shows 7 or 8 applications holding blocks for sleep, including
the Network Manager, Power Manager, etc). This is slightly different
from what I was doing earlier (where the block was put in place
immediately after receiving the sleep notification---this could lead to
problems if sleep takes over before Emacs completes its
actions. Although in practice I never encountered an actual problem).

The only other thing I had to do was figure out how to close the file
descriptor that implemented the block. According to systemd/logind its
the application's responsibility to close the descriptor to release the
block. But I couldn't find any way to do this from lisp. In the end I
just exported `emacs_close' to lisp as `emacs-close-fd' and this works
fine.  But maybe there is a different approach.

Best,
Andy
-- 
Andrew Cohen