GNU bug report logs -
#63620
30.0.50; [Feature Request] run hooks on sleep/wake
Previous Next
Full log
Message #79 received at 63620 <at> debbugs.gnu.org (full text, mbox):
>>>>> "SM" == Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
>>> Maybe a hook is not such a bad idea after all.
>> But then how would platforms where these events come from the
>> window-system call that hook?
SM> I don't understand the question: why would those not be ale to
SM> run the hook? If it's because it's in a separate UI thread,
SM> they can push to `pending_funcalls`, or in the worst case they
SM> can add an event into the event queue and then use
SM> `special-event-map` to run an ad-hoc function which runs the
SM> hook.
I remain open to other ideas, but it seems to me that the most
straightforward is to allow systems to add a sleep-event into the event
queue. My original code installed a callback function to run the hooks
when a state change is detected. So this same function can be installed
into special-event-map and the behavior on all systems is the same.
I've modified the code a bit---I've made the handler function
configurable with a defcustom and set it by default to the function that
just runs the hooks. But the same handler will be used on both
sleep-events and dbus detection. The only difference is that if the
system supports dbus, dbus detection of state changes will be used,
while in other cases sleep-events will trigger the handler.
;;; sleep.el --- run hooks on device sleep and wake -*- lexical-binding:t -*-
;; Copyright (C) 2025 Free Software Foundation, Inc.
;; Author: Andrew Cohen <>
;; Maintainer: emacs-devel <at> gnu.org
;; Keywords:
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;; This global minor mode enables evaluating code when the device
;;; running Emacs enters or leaves the sleep state. The hooks
;;; `sleep-sleep-hook' and `sleep-wake-hook' are run when the system
;;; detects that it is going to sleep or waking up. Currently only a
;;; D-Bus interface to detect sleep state change is implemented.
;;; Code:
(require 'dbus)
(defgroup sleep nil
"Run hooks on device entering/leaving the sleep state."
:group 'hardware)
(defcustom sleep-handler-function 'handle-sleep-event
"Function called on device sleep state change.
The function takes a single boolean argument (t for sleep and nil for
wake). The default function just runs the sleep and wake hooks."
:group 'sleep
:type 'function)
(defcustom sleep-sleep-hook nil
"Hook to run on device entering sleep."
:group 'sleep
:type 'hook)
(defcustom sleep-wake-hook nil
"Hook to run on device leaving sleep."
:group 'sleep
:type 'hook)
(defvar sleep-dbus-registration-object nil
"Object returned from `dbus-register-signal'.
This is recorded so that the signal may be unregistered.")
(defun sleep-dbus-detection (mode)
"Enable D-Bus detection of device sleep/wake state change.
When enabled run `sleep-handler-function' when a state change is
detected. Disable detection if MODE is nil."
(if mode
(unless sleep-dbus-registration-object
(setq sleep-dbus-registration-object
(dbus-register-signal :system
"org.freedesktop.login1"
"/org/freedesktop/login1"
"org.freedesktop.login1.Manager"
"PrepareForSleep"
sleep-handler-function)))
(condition-case nil
(progn
(ignore-error (dbus-error wrong-type-argument)
(dbus-unregister-object
sleep-dbus-registration-object))
(setq sleep-dbus-registration-object nil))
(wrong-type-argument nil))))
(defun handle-sleep-event (sleep-wake)
"Handler to execute sleep and wake functions.
SLEEP-WAKE is t on sleeping and nil on waking."
(ignore-errors
(if sleep-wake
(run-hooks 'sleep-sleep-hook)
(run-hooks 'sleep-wake-hook))))
;;;###autoload
(define-minor-mode sleep-wake-mode
"Toggle sleep/wake detection.
With `sleep-wake-mode' enabled, the hooks `sleep-sleep-hook' and
`sleep-wake-hook' will be executed when the device enters or leaves the
sleep state. This is currently only available on systems that support
D-Bus detection of sleep state changes."
:global t
:group 'sleep
(cond
((and (featurep 'dbusbind)
(member "org.freedesktop.login1"
(dbus-list-activatable-names :system)))
(sleep-dbus-detection sleep-wake-mode))
(t
(if sleep-wake-mode
(define-key special-event-map [sleep-event] sleep-handler-function)
(define-key special-event-map [sleep-event] 'ignore)))))
(provide 'sleep)
;;; sleep.el ends here
--
Andrew Cohen
This bug report was last modified 130 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.