GNU bug report logs -
#63620
30.0.50; [Feature Request] run hooks on sleep/wake
Previous Next
Full log
Message #82 received at 63620 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
If someone builds without dbus, say on macOS, does this approach work
without dbus?
On Wed, Feb 5, 2025 at 8:44 PM Andrew Cohen <acohen <at> ust.hk> wrote:
> >>>>> "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
>
[Message part 2 (text/html, inline)]
This bug report was last modified 131 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.