Package: emacs;
Reported by: Andrew Cohen <acohen <at> ust.hk>
Date: Sat, 20 May 2023 23:25:02 UTC
Severity: wishlist
Tags: patch
Found in version 30.0.50
View this message in rfc822 format
From: Andrew Cohen <acohen <at> ust.hk> To: Stefan Monnier <monnier <at> iro.umontreal.ca> Cc: 63620 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>, michael.albinus <at> gmx.de, Ship Mints <shipmints <at> gmail.com> Subject: bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake Date: Thu, 06 Feb 2025 09:43:56 +0800
>>>>> "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
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.