all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
@ 2023-05-20 23:19 Andrew Cohen
  2023-05-21  8:12 ` Michael Albinus
  0 siblings, 1 reply; 55+ messages in thread
From: Andrew Cohen @ 2023-05-20 23:19 UTC (permalink / raw)
  To: 63620

I am playing around with various network things (mostly vpn related) and
need Emacs to take certain actions when my laptop sleeps and wakes. This
is easy to do using the existing dbus support (the relevant code is
below, which runs hooks on sleeping and waking) The question is whether
this is useful enough to add to Emacs, and if so the best place to put
it.

Not too long ago, Eric Abrahamsen added gnus-dbus.el which is similar,
although for a single purpose: to close gnus server network connections
on sleep. This has a single entry point for the user: set
'gnus-dbus-close-on-sleep to t to enable the feature. 


Options:
1. Do nothing (this isn't useful enough to change anything, and I can just
keep using my own code).

2. Add a small package dbus-sleep.el. I would also remove gnus-dbus.el
but leave the variable 'gnus-dbus-close-on-sleep and use it to control
the installation of appropriate gnus functions to the new hooks.

3. 2. Add the new code to the existing dbus.el. I would also remove
gnus-dbus.el but leave the variable 'gnus-dbus-close-on-sleep and use it
to control the installation of appropriate functions to the new hooks.

I mostly favor adding it to dbus.el. The argument against: dbus.el is
focused on providing language bindings for the D-Bus API rather than a
user-feature. The removal of gnus-dbus.el shouldn't cause any problem
since I would maintain the same functionality enabled by the same
variable, so no user-visible change. 

Advice?


;;; Code:

(require 'dbus)

(defcustom dbus-sleep-sleep-hook nil
  "Hook to run on sleep."
  :group 'dbus-sleep
  :type 'hook)

(defcustom dbus-sleep-wake-hook nil
  "Hook to run on wake."
  :group 'dbus-sleep
  :type 'hook)

(defvar dbus-sleep-registration-object nil
  "Object returned from `dbus-register-signal'.
This is used to unregister the signal.")

;;;###autoload
(defun dbus-sleep-enable ()
  "Use `dbus-register-signal' to close servers on sleep."
  (interactive)
  ;; Don't enable if it's already enabled.
  (when (and (featurep 'dbusbind) (not dbus-sleep-registration-object))
    (setq dbus-sleep-registration-object
          (dbus-register-signal :system
                                "org.freedesktop.login1"
                                "/org/freedesktop/login1"
                                "org.freedesktop.login1.Manager"
                                "PrepareForSleep"
                                #'dbus-sleep-handler))))

(defun dbus-sleep-disable ()
  "Unregister sleep signal."
  (interactive)
  (condition-case nil
      (dbus-unregister-object
       dbus-sleep-registration-object)
    (setq dbus-sleep-registration-object nil)
    (wrong-type-argument nil)))

(defun dbus-sleep-handler (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 'dbus-sleep-sleep-hook)
      (run-hooks 'dbus-sleep-wake-hook))))

-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2023-05-20 23:19 bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake Andrew Cohen
@ 2023-05-21  8:12 ` Michael Albinus
  2023-06-05 13:06   ` Andrew Cohen
  0 siblings, 1 reply; 55+ messages in thread
From: Michael Albinus @ 2023-05-21  8:12 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620

Andrew Cohen <acohen@ust.hk> writes:

Hi Andrew,

> 2. Add a small package dbus-sleep.el. I would also remove gnus-dbus.el
> but leave the variable 'gnus-dbus-close-on-sleep and use it to control
> the installation of appropriate gnus functions to the new hooks.
>
> 3. Add the new code to the existing dbus.el. I would also remove
> gnus-dbus.el but leave the variable 'gnus-dbus-close-on-sleep and use it
> to control the installation of appropriate functions to the new hooks.
>
> I mostly favor adding it to dbus.el. The argument against: dbus.el is
> focused on providing language bindings for the D-Bus API rather than a
> user-feature. The removal of gnus-dbus.el shouldn't cause any problem
> since I would maintain the same functionality enabled by the same
> variable, so no user-visible change.

Using D-Bus is just an implementation detail. What you want are
handlers, which are invoked when your laptop falls asleep or awakes.

A general package could implement it using D-Bus if available, or using
something else if there's no D-Bus. See battery.el, which uses the D-Bus
service "org.freedesktop.UPower" only if possible. Your package might be
called sleep.el or alike.

Your code uses the D-Bus service "org.freedesktop.login1", which isn't
part of the basic D-Bus spec. So it isn't suited for dbus.el anyway.

> ;;;###autoload
> (defun dbus-sleep-enable ()
>   "Use `dbus-register-signal' to close servers on sleep."
>   (interactive)

I would make it rather a global minor mode, that you can enable/disable
it easily.

>   ;; Don't enable if it's already enabled.
>   (when (and (featurep 'dbusbind) (not dbus-sleep-registration-object))

Perhaps, you check also for the service "org.freedesktop.login1", like

--8<---------------cut here---------------start------------->8---
(member "org.freedesktop.login1" (dbus-list-activatable-names :system))
--8<---------------cut here---------------end--------------->8---

This check might return nil for several reasons, like the system bus is
not running, or you don't have permissions to speak to the system bus,
or the service simply doesn't exist.

Best regards, Michael.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2023-05-21  8:12 ` Michael Albinus
@ 2023-06-05 13:06   ` Andrew Cohen
  2023-06-10 10:47     ` Michael Albinus
  0 siblings, 1 reply; 55+ messages in thread
From: Andrew Cohen @ 2023-06-05 13:06 UTC (permalink / raw)
  To: Michael Albinus; +Cc: 63620

[-- Attachment #1: Type: text/plain, Size: 1419 bytes --]

Dear Michael

>>>>> "MA" == Michael Albinus <michael.albinus@gmx.de> writes:

[...]

    MA> Using D-Bus is just an implementation detail. What you want are
    MA> handlers, which are invoked when your laptop falls asleep or
    MA> awakes.

Yes, of course you are right!

    MA> A general package could implement it using D-Bus if available,
    MA> or using something else if there's no D-Bus. See battery.el,
    MA> which uses the D-Bus service "org.freedesktop.UPower" only if
    MA> possible. Your package might be called sleep.el or alike.

I am not familiar with other methods for detecting sleep/wake, so I just
have dbus at the moment. But if anyone knows of something else
(especially on windows) it can then be added.

[...]

MA> I would make it rather a global minor mode, that you can
MA> enable/disable it easily.

Yes, that is a better idea. 

[...]

    MA> Perhaps, you check also for the service
    MA> "org.freedesktop.login1", like

    MA> (member "org.freedesktop.login1" (dbus-list-activatable-names
    MA> :system))

OK, added.


I've now put everything together and modified the gnus code to use the
new sleep.el. But I remain unsure if I should remove gnus-dbus.el
entirely (everything remains the same for the user: setting
gnus-dbus-close-on-sleep to a non-nil value will enable the feature
using the global minor mode rather than gnus-dbus).  And is sleep.el
something worth adding?


[-- Attachment #2: sleep.el --]
[-- Type: application/emacs-lisp, Size: 3425 bytes --]

[-- Attachment #3: Type: text/plain, Size: 19 bytes --]



-- 
Andrew Cohen

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2023-06-05 13:06   ` Andrew Cohen
@ 2023-06-10 10:47     ` Michael Albinus
  2025-02-04  3:19       ` Andrew Cohen
  0 siblings, 1 reply; 55+ messages in thread
From: Michael Albinus @ 2023-06-10 10:47 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620

Andrew Cohen <acohen@ust.hk> writes:

> Dear Michael

Hi Andrew,

sorry for the delayed answer, I've been busy ...

> I've now put everything together and modified the gnus code to use the
> new sleep.el. But I remain unsure if I should remove gnus-dbus.el
> entirely (everything remains the same for the user: setting
> gnus-dbus-close-on-sleep to a non-nil value will enable the feature
> using the global minor mode rather than gnus-dbus).  And is sleep.el
> something worth adding?

It depends whether sleep.el will be added to vanilla Emacs, or as GNU
ELPA package. It's not my decision, but I lobby for the former.

In this case, it could be used in gnus-dbus.el.

Just some few comments on the code

> ;;; sleep.el --- run hooks on sleep and wake  -*- lexical-binding:t -*-

I would be more precise. You don't mean sleeping Emacs or another
application, but you mean sleeping the machine on OS level. Say it so.

> ;;; This global minor mode enables evaluating code when the device
> ;;; running Emacs enters or leaves the sleep state.  Two hooks are
> ;;; used, sleep-sleep-hook and sleep-wake-hook, run when the system
> ;;; detects that it is going to sleep or waking up.  Currently only a
> ;;; dbus interface to detect sleep state change is implemented.

Please quote Lisp objects like `sleep-sleep-hook'. D-Bus is spelled out
in commentaries as D-Bus.

> (defgroup sleep nil
>   "Run hooks on entering/leaving the sleep state."
>   :group 'hardware)
>
> (defcustom sleep-sleep-hook nil
>   "Hook to run on entering sleep."
>   :group 'sleep
>   :type 'hook)
>
> (defcustom sleep-wake-hook nil
>   "Hook to run on leaving sleep."
>   :group 'sleep
>   :type 'hook)

These are the user visible objects. Please be precise what is going to
sleep. The machine or device.

> Run sleep-sleep-hook and sleep-wake-hook as appropriate."

Please quote sleep-sleep-hook.

>   (unless sleep-registration-object
>     (setq sleep-registration-object
>           (dbus-register-signal :system
>                                 "org.freedesktop.login1"
>                                 "/org/freedesktop/login1"
>                                 "org.freedesktop.login1.Manager"
>                                 "PrepareForSleep"
>                                 #'sleep-handler))))

I would also protect against D-Bus errors. Like

(ignore-error dbus-error
  (unless sleep-registration-object
    (setq sleep-registration-object
          (dbus-register-signal
	   :system "org.freedesktop.login1"
           "/org/freedesktop/login1" "org.freedesktop.login1.Manager"
           "PrepareForSleep" #'sleep-handler))))

>   (condition-case nil
>       (progn
>         (dbus-unregister-object
>          sleep-registration-object)
>         (setq sleep-registration-object nil))
>     (wrong-type-argument nil)))

Aka

(ignore-error (dbus-error wrong-type-argument)
  (dbus-unregister-object
   sleep-registration-object)
  (setq sleep-registration-object nil))

> When sleep-wake-mode is enabled, Emacs will execute the hooks

Please quote sleep-wake-mode.

> support dbus detection of sleep state change."

D-Bus is spelled out ...

Furthermore, it would be nice if you add

- documentation in lispref node "(elisp) System Interface". I'm not sure
  whether it is good for a new subnode, or whether it shall be
  documented in "(elisp) System Environment". This documentation should
  also give a practical example for functions in sleep-sleep-hook and
  sleep-wake-hook.

- adding the functionality to etc/NEWS

- if possible, adding tests in test/lisp/sleep-tests.el

Best regards, Michael.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2023-06-10 10:47     ` Michael Albinus
@ 2025-02-04  3:19       ` Andrew Cohen
  2025-02-04 13:16         ` Eli Zaretskii
  0 siblings, 1 reply; 55+ messages in thread
From: Andrew Cohen @ 2025-02-04  3:19 UTC (permalink / raw)
  To: Michael Albinus; +Cc: 63620

I have not had much time for Emacs outside of my regular activities, but
I made the changes you suggested and have been using the package for the
past year. Unless I hear objections, I'll push the package to master
sometime soon.

Best,
Andy

ea288bd05e7d11740f5d580771ed7ca5ad496b15
Author:     Andrew G Cohen <cohen@andy.bu.edu>
AuthorDate: Thu Mar 21 11:06:36 2024 +0800
Commit:     Andrew G Cohen <cohen@andy.bu.edu>
CommitDate: Tue Feb 4 11:14:26 2025 +0800

Parent:     c54d8d4cbe0 New functions to suspend and resume gnus demon
Merged:     master
Contained:  feature/igc
Follows:    emacs-29.1.90 (176369)

New sleep-wake-mode to run hooks on sleep state change

* lisp/sleep.el: New global minor mode. When enabled, the hooks
sleep-wake-hook and sleep-sleep-hook are run on the corresponding sleep
state change.

2 files changed, 112 insertions(+)
etc/NEWS      |   6 ++++
lisp/sleep.el | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

modified   etc/NEWS
@@ -1015,6 +1015,12 @@ destination window is chosen using 'display-buffer-alist'.  Example:
 \f
 * New Modes and Packages in Emacs 31.1
 
+** New global minor mode 'sleep-wake'.
+With this minor mode enabled, the hooks 'sleep-sleep-hook' and
+'sleep-wake-hook' are run when the device running Emacs enters or leaves
+the sleep state. Currently only D-Bus detection of device sleep state
+changes is available.
+
 \f
 * Incompatible Lisp Changes in Emacs 31.1
 
new file   lisp/sleep.el
@@ -0,0 +1,106 @@
+;;; 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@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-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-registration-object nil
+  "Object returned from `dbus-register-signal'.
+This is recorded so that the signal may be unregistered.")
+
+
+(defun sleep-dbus-enable ()
+  "Enable D-Bus detection of device sleep/wake state change.
+Run `sleep-sleep-hook' and `sleep-wake-hook' as appropriate."
+  (unless sleep-registration-object
+    (setq sleep-registration-object
+          (dbus-register-signal :system
+                                "org.freedesktop.login1"
+                                "/org/freedesktop/login1"
+                                "org.freedesktop.login1.Manager"
+                                "PrepareForSleep"
+                                #'sleep-handler))))
+
+(defun sleep-dbus-disable ()
+  "Disable D-Bus detection of device sleep/wake state change."
+  (condition-case nil
+      (progn
+        (ignore-error (dbus-error wrong-type-argument)
+          (dbus-unregister-object
+           sleep-registration-object))
+        (setq sleep-registration-object nil))
+    (wrong-type-argument nil)))
+
+(defun sleep-handler (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)))
+    (if sleep-wake-mode
+        (sleep-dbus-enable)
+      (sleep-dbus-disable)))
+   (t
+    (message "No sleep/wake detection method found."))))
+
+(provide 'sleep)
+;;; sleep.el ends here


-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04  3:19       ` Andrew Cohen
@ 2025-02-04 13:16         ` Eli Zaretskii
  2025-02-04 13:38           ` Andrew Cohen
  0 siblings, 1 reply; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-04 13:16 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, michael.albinus, Stefan Monnier

> Cc: 63620@debbugs.gnu.org
> From: Andrew Cohen <acohen@ust.hk>
> Date: Tue, 04 Feb 2025 11:19:55 +0800
> 
> I have not had much time for Emacs outside of my regular activities, but
> I made the changes you suggested and have been using the package for the
> past year. Unless I hear objections, I'll push the package to master
> sometime soon.

Thanks, but could we perhaps implement this in a way that is less
modeled on D-Bus, thus allowing different back-ends on other systems?
For example, could we have the D-Bus backend inject an input event,
which could then be bound to a command, instead of directly calling
the hooks from a D-Bus event handler?  That would allow adding other
backend, which will generate the same input event "by other means".

Stefan and Michael, I'd appreciate your comments, both on the patch
and on my proposal.  Maybe you will have other, better design ideas.
(FWIW, I've read Michael's original comments in this bug report as
saying things similar to what I say above.  But either I misunderstood
or the patch as posted doesn't do what Michael suggested back then.)





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 13:16         ` Eli Zaretskii
@ 2025-02-04 13:38           ` Andrew Cohen
  2025-02-04 14:49             ` Eli Zaretskii
  2025-02-04 14:55             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 55+ messages in thread
From: Andrew Cohen @ 2025-02-04 13:38 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 63620, michael.albinus, Stefan Monnier

>>>>> "EZ" == Eli Zaretskii <eliz@gnu.org> writes:

    >> Cc: 63620@debbugs.gnu.org From: Andrew Cohen <acohen@ust.hk>
    >> Date: Tue, 04 Feb 2025 11:19:55 +0800
    >> 
    >> I have not had much time for Emacs outside of my regular
    >> activities, but I made the changes you suggested and have been
    >> using the package for the past year. Unless I hear objections,
    >> I'll push the package to master sometime soon.

    EZ> Thanks, but could we perhaps implement this in a way that is
    EZ> less modeled on D-Bus, thus allowing different back-ends on
    EZ> other systems?  For example, could we have the D-Bus backend
    EZ> inject an input event, which could then be bound to a command,
    EZ> instead of directly calling the hooks from a D-Bus event
    EZ> handler?  That would allow adding other backend, which will
    EZ> generate the same input event "by other means".

    EZ> Stefan and Michael, I'd appreciate your comments, both on the
    EZ> patch and on my proposal.  Maybe you will have other, better
    EZ> design ideas.  (FWIW, I've read Michael's original comments in
    EZ> this bug report as saying things similar to what I say above.
    EZ> But either I misunderstood or the patch as posted doesn't do
    EZ> what Michael suggested back then.)


Thanks, I'm happy to make changes. I think I understand what you are
suggesting (and what Michael suggested earlier) and it is certainly
desirable to make this more independent of D-Bus. My programming skills
are extremely rudimentary so it might take some time (or I might fail
altogether).

Best,
Andy

-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 13:38           ` Andrew Cohen
@ 2025-02-04 14:49             ` Eli Zaretskii
  2025-02-05 12:51               ` Andrew Cohen
  2025-02-04 14:55             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-04 14:49 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, michael.albinus, monnier

> From: Andrew Cohen <acohen@ust.hk>
> Cc: <michael.albinus@gmx.de>,  Stefan Monnier <monnier@iro.umontreal.ca>,
>   <63620@debbugs.gnu.org>
> Date: Tue, 04 Feb 2025 21:38:53 +0800
> 
> Thanks, I'm happy to make changes. I think I understand what you are
> suggesting (and what Michael suggested earlier) and it is certainly
> desirable to make this more independent of D-Bus. My programming skills
> are extremely rudimentary so it might take some time (or I might fail
> altogether).

Thanks, and don't hesitate to ask questions where you have
difficulties.  I'm sure you will find here quite a few people willing
to help.

To make it clear: I think this is a very useful feature to have in
Emacs, given today's proliferation of laptops and devices that like to
go to sleep, so I hope we will be able to make it work on as many
platforms as possible.  Which is why I think we should try
implementing it using the most portable and flexible mechanisms we
have of triggering stuff in Emacs.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 13:38           ` Andrew Cohen
  2025-02-04 14:49             ` Eli Zaretskii
@ 2025-02-04 14:55             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-04 15:21               ` Ship Mints
  1 sibling, 1 reply; 55+ messages in thread
From: Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-04 14:55 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, Eli Zaretskii, Stefan Monnier

Andrew Cohen <acohen@ust.hk> writes:

Hi,

>     >> I have not had much time for Emacs outside of my regular
>     >> activities, but I made the changes you suggested and have been
>     >> using the package for the past year. Unless I hear objections,
>     >> I'll push the package to master sometime soon.
>
>     EZ> Thanks, but could we perhaps implement this in a way that is
>     EZ> less modeled on D-Bus, thus allowing different back-ends on
>     EZ> other systems?  For example, could we have the D-Bus backend
>     EZ> inject an input event, which could then be bound to a command,
>     EZ> instead of directly calling the hooks from a D-Bus event
>     EZ> handler?  That would allow adding other backend, which will
>     EZ> generate the same input event "by other means".
>
>     EZ> Stefan and Michael, I'd appreciate your comments, both on the
>     EZ> patch and on my proposal.  Maybe you will have other, better
>     EZ> design ideas.  (FWIW, I've read Michael's original comments in
>     EZ> this bug report as saying things similar to what I say above.
>     EZ> But either I misunderstood or the patch as posted doesn't do
>     EZ> what Michael suggested back then.)
>
>
> Thanks, I'm happy to make changes. I think I understand what you are
> suggesting (and what Michael suggested earlier) and it is certainly
> desirable to make this more independent of D-Bus. My programming skills
> are extremely rudimentary so it might take some time (or I might fail
> altogether).

Yes, I still believe my proposal stands. OTOH, nobody else has taken the
stab over the last months, so I don't know whether such changes will
happen.

FTR, the majority of my comments on the code are integrated. What's left
could be done later. What I'm missing is the documentation in the Elisp
manual, if we integrate it into Emacs core.

> Best,
> Andy

Best regards Michael.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 14:55             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-04 15:21               ` Ship Mints
  2025-02-04 15:30                 ` Eli Zaretskii
  0 siblings, 1 reply; 55+ messages in thread
From: Ship Mints @ 2025-02-04 15:21 UTC (permalink / raw)
  To: Michael Albinus; +Cc: Andrew Cohen, 63620, Eli Zaretskii, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 2450 bytes --]

Once an API is agreed in principle, I'd be willing to take a stab at an NS
implementation for sleep/wake events to exercise the API, and so we'd have
both dbus and NS. On macOS, it's basically "will sleep" and "did wake"
events, and I don't think there's a hibernate event.

On Tue, Feb 4, 2025 at 9:56 AM Michael Albinus via Bug reports for GNU
Emacs, the Swiss army knife of text editors <bug-gnu-emacs@gnu.org> wrote:

> Andrew Cohen <acohen@ust.hk> writes:
>
> Hi,
>
> >     >> I have not had much time for Emacs outside of my regular
> >     >> activities, but I made the changes you suggested and have been
> >     >> using the package for the past year. Unless I hear objections,
> >     >> I'll push the package to master sometime soon.
> >
> >     EZ> Thanks, but could we perhaps implement this in a way that is
> >     EZ> less modeled on D-Bus, thus allowing different back-ends on
> >     EZ> other systems?  For example, could we have the D-Bus backend
> >     EZ> inject an input event, which could then be bound to a command,
> >     EZ> instead of directly calling the hooks from a D-Bus event
> >     EZ> handler?  That would allow adding other backend, which will
> >     EZ> generate the same input event "by other means".
> >
> >     EZ> Stefan and Michael, I'd appreciate your comments, both on the
> >     EZ> patch and on my proposal.  Maybe you will have other, better
> >     EZ> design ideas.  (FWIW, I've read Michael's original comments in
> >     EZ> this bug report as saying things similar to what I say above.
> >     EZ> But either I misunderstood or the patch as posted doesn't do
> >     EZ> what Michael suggested back then.)
> >
> >
> > Thanks, I'm happy to make changes. I think I understand what you are
> > suggesting (and what Michael suggested earlier) and it is certainly
> > desirable to make this more independent of D-Bus. My programming skills
> > are extremely rudimentary so it might take some time (or I might fail
> > altogether).
>
> Yes, I still believe my proposal stands. OTOH, nobody else has taken the
> stab over the last months, so I don't know whether such changes will
> happen.
>
> FTR, the majority of my comments on the code are integrated. What's left
> could be done later. What I'm missing is the documentation in the Elisp
> manual, if we integrate it into Emacs core.
>
> > Best,
> > Andy
>
> Best regards Michael.
>
>
>
>

[-- Attachment #2: Type: text/html, Size: 3251 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 15:21               ` Ship Mints
@ 2025-02-04 15:30                 ` Eli Zaretskii
  2025-02-04 15:35                   ` Ship Mints
                                     ` (2 more replies)
  0 siblings, 3 replies; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-04 15:30 UTC (permalink / raw)
  To: michael.albinus, Ship Mints; +Cc: acohen, 63620, monnier

> From: Ship Mints <shipmints@gmail.com>
> Date: Tue, 4 Feb 2025 10:21:05 -0500
> Cc: Andrew Cohen <acohen@ust.hk>, 63620@debbugs.gnu.org, Eli Zaretskii <eliz@gnu.org>, 
> 	Stefan Monnier <monnier@iro.umontreal.ca>
> 
> Once an API is agreed in principle, I'd be willing to take a stab at an NS implementation for sleep/wake
> events to exercise the API, and so we'd have both dbus and NS. On macOS, it's basically "will sleep" and
> "did wake" events, and I don't think there's a hibernate event.

What I had in mind is basically to have the D-Bus handler push a
special event onto unread-command-events, and then that event could be
bound to a command.

Michael and Stefan, does it make sense to work like that with D-Bus?





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 15:30                 ` Eli Zaretskii
@ 2025-02-04 15:35                   ` Ship Mints
  2025-02-04 15:42                     ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-04 16:12                     ` Eli Zaretskii
  2025-02-04 15:38                   ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-04 18:14                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2 siblings, 2 replies; 55+ messages in thread
From: Ship Mints @ 2025-02-04 15:35 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: acohen, 63620, michael.albinus, monnier

[-- Attachment #1: Type: text/plain, Size: 895 bytes --]

This would be kbd_buffer_store_event?

On Tue, Feb 4, 2025 at 10:31 AM Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Ship Mints <shipmints@gmail.com>
> > Date: Tue, 4 Feb 2025 10:21:05 -0500
> > Cc: Andrew Cohen <acohen@ust.hk>, 63620@debbugs.gnu.org, Eli Zaretskii <
> eliz@gnu.org>,
> >       Stefan Monnier <monnier@iro.umontreal.ca>
> >
> > Once an API is agreed in principle, I'd be willing to take a stab at an
> NS implementation for sleep/wake
> > events to exercise the API, and so we'd have both dbus and NS. On macOS,
> it's basically "will sleep" and
> > "did wake" events, and I don't think there's a hibernate event.
>
> What I had in mind is basically to have the D-Bus handler push a
> special event onto unread-command-events, and then that event could be
> bound to a command.
>
> Michael and Stefan, does it make sense to work like that with D-Bus?
>

[-- Attachment #2: Type: text/html, Size: 1638 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 15:30                 ` Eli Zaretskii
  2025-02-04 15:35                   ` Ship Mints
@ 2025-02-04 15:38                   ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-04 18:14                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2 siblings, 0 replies; 55+ messages in thread
From: Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-04 15:38 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: acohen, 63620, Ship Mints, monnier

Eli Zaretskii <eliz@gnu.org> writes:

>> Once an API is agreed in principle, I'd be willing to take a stab at an NS implementation for sleep/wake
>> events to exercise the API, and so we'd have both dbus and NS. On macOS, it's basically "will sleep" and
>> "did wake" events, and I don't think there's a hibernate event.
>
> What I had in mind is basically to have the D-Bus handler push a
> special event onto unread-command-events, and then that event could be
> bound to a command.
>
> Michael and Stefan, does it make sense to work like that with D-Bus?

Sure, no problem for D-Bus. This could be done in sleep-handler, instead
of running sleep-sleep-hook and sleep-wake-hook.

The event should have a boolean argument, for on/off (or sleep/wake,
however we name it).

Best regards, Michael.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 15:35                   ` Ship Mints
@ 2025-02-04 15:42                     ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-04 15:51                       ` Ship Mints
  2025-02-04 16:12                     ` Eli Zaretskii
  1 sibling, 1 reply; 55+ messages in thread
From: Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-04 15:42 UTC (permalink / raw)
  To: Ship Mints; +Cc: acohen, 63620, Eli Zaretskii, monnier

Ship Mints <shipmints@gmail.com> writes:

> This would be kbd_buffer_store_event?

On Lisp level, adding the event to unread-command-events, as Eli
said. See a similar handling in dbus-call-method.

>     What I had in mind is basically to have the D-Bus handler push a
>     special event onto unread-command-events, and then that event
>     could be
>     bound to a command.

Best regards, Michael.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 15:42                     ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-04 15:51                       ` Ship Mints
  2025-02-04 16:15                         ` Eli Zaretskii
  0 siblings, 1 reply; 55+ messages in thread
From: Ship Mints @ 2025-02-04 15:51 UTC (permalink / raw)
  To: Michael Albinus; +Cc: acohen, 63620, Eli Zaretskii, monnier

[-- Attachment #1: Type: text/plain, Size: 644 bytes --]

For macOS, we'll have to do this via objective-c so would be the
lower-level function that would post the event.

On Tue, Feb 4, 2025 at 10:42 AM Michael Albinus <michael.albinus@gmx.de>
wrote:

> Ship Mints <shipmints@gmail.com> writes:
>
> > This would be kbd_buffer_store_event?
>
> On Lisp level, adding the event to unread-command-events, as Eli
> said. See a similar handling in dbus-call-method.
>
> >     What I had in mind is basically to have the D-Bus handler push a
> >     special event onto unread-command-events, and then that event
> >     could be
> >     bound to a command.
>
> Best regards, Michael.
>

[-- Attachment #2: Type: text/html, Size: 1126 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 15:35                   ` Ship Mints
  2025-02-04 15:42                     ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-04 16:12                     ` Eli Zaretskii
  1 sibling, 0 replies; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-04 16:12 UTC (permalink / raw)
  To: Ship Mints; +Cc: acohen, 63620, michael.albinus, monnier

> From: Ship Mints <shipmints@gmail.com>
> Date: Tue, 4 Feb 2025 10:35:03 -0500
> Cc: michael.albinus@gmx.de, acohen@ust.hk, 63620@debbugs.gnu.org, 
> 	monnier@iro.umontreal.ca
> 
> This would be kbd_buffer_store_event?

Basically, yes.  But I meant to do it in Lisp, not in C.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 15:51                       ` Ship Mints
@ 2025-02-04 16:15                         ` Eli Zaretskii
  0 siblings, 0 replies; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-04 16:15 UTC (permalink / raw)
  To: Ship Mints; +Cc: acohen, 63620, michael.albinus, monnier

> From: Ship Mints <shipmints@gmail.com>
> Date: Tue, 4 Feb 2025 10:51:11 -0500
> Cc: Eli Zaretskii <eliz@gnu.org>, acohen@ust.hk, 63620@debbugs.gnu.org, 
> 	monnier@iro.umontreal.ca
> 
> For macOS, we'll have to do this via objective-c so would be the lower-level function that would post the
> event.

Yes, platforms that get the event from their window-systems should do
it in C.  Then we'd need to define a new event kind and inject it.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 15:30                 ` Eli Zaretskii
  2025-02-04 15:35                   ` Ship Mints
  2025-02-04 15:38                   ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-04 18:14                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2 siblings, 0 replies; 55+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-04 18:14 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: acohen, 63620, michael.albinus, Ship Mints

> What I had in mind is basically to have the D-Bus handler push a
> special event onto unread-command-events, and then that event could be
> bound to a command.
> Michael and Stefan, does it make sense to work like that with D-Bus?

It would likely be bound in `special-event-map`, yes, that makes sense.


        Stefan






^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-04 14:49             ` Eli Zaretskii
@ 2025-02-05 12:51               ` Andrew Cohen
  2025-02-05 13:27                 ` Andrew Cohen
  0 siblings, 1 reply; 55+ messages in thread
From: Andrew Cohen @ 2025-02-05 12:51 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 63620, michael.albinus, monnier

>>>>> "EZ" == Eli Zaretskii <eliz@gnu.org> writes:

    EZ> Thanks, and don't hesitate to ask questions where you have
    EZ> difficulties.  I'm sure you will find here quite a few people
    EZ> willing to help.

OK, I have almost no idea what I am doing. I am trying to understand how
to use unread-command-events to make this work. I guess a new event
(sleep-event) will get added in the C code? Then backends other than
dbus will generate this event when a system sleeps or wakes, and we have
a handler installed like

(define-key special-event-map [sleep-event] 'handle-sleep-event)

with the function 'handle-sleep-event that runs the appropriate hooks.

For the dbus backend we install a dbus callback that injects the
sleep-event onto unread-command-events, which would then trigger the
'handle-sleep-event function. 

So I thought I would play around a bit. I tried installing [sleep-event]
in the special-event map, but when I push the sleep-event onto
unread-command-events I get an error: "<sleep-event> is undefined".
After playing around I found that if I also install it in the global
keymap, it works (that is, pushing a sleep-event onto
unread-command-events then triggers the handler).

So how exactly do I add a new sleep-event to the C source? I tried
copying how its done for dbus-event in keyboard.c and termhooks.h (I'm
only trying to create such an event in lisp so I didn't worry about
generating such an event in C). Is this right? And do I always have to
install the handler in the global keymap (just to test this I tried
pushing an existing dbus-event onto unread-command-events, and also get
"dbus-event is undefined" unless I install a handler on the global
keymap. So it seems that I do. I also notice that other special events,
like delete-frame, have handlers installed in both the global keymap and
the special-event-map).

Sorry for the very naive questions. Assuming that my understanding is
correct I think I can make the necessary modifications to the lisp
package. Then the C code to generate the sleep-event on other systems
can be added.

Best,
Andy
-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-05 12:51               ` Andrew Cohen
@ 2025-02-05 13:27                 ` Andrew Cohen
  2025-02-05 15:28                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 55+ messages in thread
From: Andrew Cohen @ 2025-02-05 13:27 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 63620, michael.albinus, monnier

>>>>> "AC" == Andrew Cohen <acohen@ust.hk> writes:

[...]

    AC> So how exactly do I add a new sleep-event to the C source? I
    AC> tried copying how its done for dbus-event in keyboard.c and
    AC> termhooks.h (I'm only trying to create such an event in lisp so
    AC> I didn't worry about generating such an event in C). Is this
    AC> right? And do I always have to install the handler in the global
    AC> keymap (just to test this I tried pushing an existing dbus-event
    AC> onto unread-command-events, and also get "dbus-event is
    AC> undefined" unless I install a handler on the global keymap. So
    AC> it seems that I do. I also notice that other special events,
    AC> like delete-frame, have handlers installed in both the global
    AC> keymap and the special-event-map).

And maybe answering my own questions:

According the the elisp manual special events "cannot be unread with
‘unread-command-events’". Not sure exactly what this means (and I
haven't yet read the code to figure it out) but it certainly appears
that special events can't trigger a function bound in special-event-map
by pushing an event onto unread-command-events. But that's probably OK,
since we can /also/ bind the handler to the special event in the global
keymap, as is done for several of the existing special events
(delete-frame, make-frame-visible, iconify-frame). Then we can trigger
the event directly in C by generating the special event, or
synthetically in Lisp by pushing onto unread-command-events. 

I'll assume that this is OK unless I hear otherwise and make changes to
the package accordingly.

Best,
Andy
-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-05 13:27                 ` Andrew Cohen
@ 2025-02-05 15:28                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-05 18:21                     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 55+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-05 15:28 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, Eli Zaretskii, michael.albinus

> According the the elisp manual special events "cannot be unread with
> ‘unread-command-events’".

Oh, right!  So pushing to `unread-command-events` will only work if the
binding is made in a normal map.  That's not the end of the world, but
it's not ideal.  E.g. it doesn't really make sense to have the behavior
depend on the mode of the current buffer, and it seems undesirable to
fail to run the binding if you happened to type `C-x` just
before sleeping.

Hmm...


        Stefan






^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-05 15:28                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-05 18:21                     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-05 20:21                       ` Eli Zaretskii
  0 siblings, 1 reply; 55+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-05 18:21 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, Eli Zaretskii, michael.albinus

>> According the the elisp manual special events "cannot be unread with
>> ‘unread-command-events’".
> Oh, right!  So pushing to `unread-command-events` will only work if the
> binding is made in a normal map.  That's not the end of the world, but
> it's not ideal.  E.g. it doesn't really make sense to have the behavior
> depend on the mode of the current buffer, and it seems undesirable to
> fail to run the binding if you happened to type `C-x` just
> before sleeping.

Maybe a hook is not such a bad idea after all.


        Stefan






^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-05 18:21                     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-05 20:21                       ` Eli Zaretskii
  2025-02-05 22:37                         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-05 20:21 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: acohen, 63620, michael.albinus

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: Eli Zaretskii <eliz@gnu.org>,  63620@debbugs.gnu.org,
>   michael.albinus@gmx.de
> Date: Wed, 05 Feb 2025 13:21:41 -0500
> 
> >> According the the elisp manual special events "cannot be unread with
> >> ‘unread-command-events’".
> > Oh, right!  So pushing to `unread-command-events` will only work if the
> > binding is made in a normal map.  That's not the end of the world, but
> > it's not ideal.  E.g. it doesn't really make sense to have the behavior
> > depend on the mode of the current buffer, and it seems undesirable to
> > fail to run the binding if you happened to type `C-x` just
> > before sleeping.
> 
> 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?  We'd need two different mechanisms for
the same feature, and two different ways of calling user-defined
functions when the event comes in.  Or what am I missing?





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-05 20:21                       ` Eli Zaretskii
@ 2025-02-05 22:37                         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06  1:43                           ` Andrew Cohen
  2025-02-06  8:26                           ` Eli Zaretskii
  0 siblings, 2 replies; 55+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-05 22:37 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: acohen, 63620, michael.albinus

>> 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?

I don't understand the question: why would those not be ale to run the
hook?  If it's because it's in a separate UI thread, they can push to
`pending_funcalls`, or in the worst case they can add an event into the
event queue and then use `special-event-map` to run an ad-hoc function
which runs the hook.

Of course, we could similarly make the D-bus code manually do
(lookup-key special-event-map [sleep-event])


        Stefan






^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-05 22:37                         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06  1:43                           ` Andrew Cohen
  2025-02-06  2:06                             ` Ship Mints
  2025-02-06  8:26                           ` Eli Zaretskii
  1 sibling, 1 reply; 55+ messages in thread
From: Andrew Cohen @ 2025-02-06  1:43 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 63620, Eli Zaretskii, michael.albinus, Ship Mints

>>>>> "SM" == Stefan Monnier <monnier@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@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





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06  1:43                           ` Andrew Cohen
@ 2025-02-06  2:06                             ` Ship Mints
  2025-02-06  2:20                               ` Andrew Cohen
  0 siblings, 1 reply; 55+ messages in thread
From: Ship Mints @ 2025-02-06  2:06 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, Eli Zaretskii, michael.albinus, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 5828 bytes --]

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@ust.hk> wrote:

> >>>>> "SM" == Stefan Monnier <monnier@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@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
>

[-- Attachment #2: Type: text/html, Size: 7225 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06  2:06                             ` Ship Mints
@ 2025-02-06  2:20                               ` Andrew Cohen
  2025-02-06  2:26                                 ` Ship Mints
  2025-02-06  5:20                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 55+ messages in thread
From: Andrew Cohen @ 2025-02-06  2:20 UTC (permalink / raw)
  To: Ship Mints; +Cc: 63620, Eli Zaretskii, michael.albinus, Stefan Monnier

>>>>> "SM" == Ship Mints <shipmints@gmail.com> writes:

    SM> If someone builds without dbus, say on macOS, does this approach
    SM> work without dbus?

This assumes that detection of sleep/wake state changes will be added to
the C source (as you offered to implement for NS :)). The idea is that
you add code to detect the change at the OS level, and then create an
event of type sleep-event with an argument of t for sleep and nil for
wake.  The lisp package detects the sleep-event and runs the appropriate
code.

It won't work quite yet (this was just showing the concept) since the C
code has to be written, and the handler function needs to accept either
an event (a cons) or a boolean. But if everyone thinks this is a valid
approach we can take care of this.

Best,
Andy
-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06  2:20                               ` Andrew Cohen
@ 2025-02-06  2:26                                 ` Ship Mints
  2025-02-06  5:20                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 55+ messages in thread
From: Ship Mints @ 2025-02-06  2:26 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, Eli Zaretskii, michael.albinus, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 1070 bytes --]

I didn't read the code yet so I'm glad this approach doesn't depend on
dbus.

I will happily work on the NS event generation. I can prototype any time
we're ready.

On Wed, Feb 5, 2025 at 21:20 Andrew Cohen <acohen@ust.hk> wrote:

> >>>>> "SM" == Ship Mints <shipmints@gmail.com> writes:
>
>     SM> If someone builds without dbus, say on macOS, does this approach
>     SM> work without dbus?
>
> This assumes that detection of sleep/wake state changes will be added to
> the C source (as you offered to implement for NS :)). The idea is that
> you add code to detect the change at the OS level, and then create an
> event of type sleep-event with an argument of t for sleep and nil for
> wake.  The lisp package detects the sleep-event and runs the appropriate
> code.
>
> It won't work quite yet (this was just showing the concept) since the C
> code has to be written, and the handler function needs to accept either
> an event (a cons) or a boolean. But if everyone thinks this is a valid
> approach we can take care of this.
>
> Best,
> Andy
> --
> Andrew Cohen
>

[-- Attachment #2: Type: text/html, Size: 1615 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06  2:20                               ` Andrew Cohen
  2025-02-06  2:26                                 ` Ship Mints
@ 2025-02-06  5:20                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06  5:59                                   ` Andrew Cohen
                                                     ` (2 more replies)
  1 sibling, 3 replies; 55+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-06  5:20 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, Eli Zaretskii, michael.albinus, Ship Mints

> The idea is that you add code to detect the change at the OS level,
> and then create an event of type sleep-event with an argument of t for
> sleep and nil for wake.  The lisp package detects the sleep-event and
> runs the appropriate code.

BTW: I understand what a "wake" event means, but what about
a "sleep" event?  I mean: how can we receive this event before we wake
up again?  Or does it mean that we're about to sleep?  If so what do we
know about when we'll sleep?  Can we influence (e.g. delay) it?


        Stefan






^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06  5:20                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06  5:59                                   ` Andrew Cohen
  2025-02-06  7:32                                   ` Andrew Cohen
  2025-02-06 10:54                                   ` Ship Mints
  2 siblings, 0 replies; 55+ messages in thread
From: Andrew Cohen @ 2025-02-06  5:59 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 63620, Eli Zaretskii, michael.albinus, Ship Mints

>>>>> "SM" == Stefan Monnier <monnier@iro.umontreal.ca> writes:

[...]

    SM> BTW: I understand what a "wake" event means, but what about a
    SM> "sleep" event?  I mean: how can we receive this event before we
    SM> wake up again?  Or does it mean that we're about to sleep?  

The events that I am detecting with D-Bus are actually part of logind, a
tiny daemon that manages user logins in various ways. The process
monitors the status of a variety of hardware components (such as the
state of the lid, power, etc), and is responsible for managing
suspension and hibernation.  I think that logind, part of
freedesktop.org, is pretty universal on gnu/linux.

The signal I am accessing, PrepareForSleep, is sent right before the
systems enters suspend/hibernate (with argument True), and right after
the system leaves suspend/hibernate (with argument False). 

    SM> If so what do we know about when we'll sleep?  

I don't think there is a guarantee how much time remains before the
sleep state is fully realized. However I've been using this for a couple
of years and have never had a failure to run the hooks to completion.

    SM> Can we influence (e.g. delay) it?

logind has a method to inhibit sleeping (exposed through D-Bus), which
can be used to create an inhibition lock, preventing sleep until the
lock is released. It would be ideal to implement this around running the
hooks to ensure that all the Emacs code completes before finishing
sleep. It shouldn't be hard, I just haven't found it necessary. I'll
take a look. And its probably important to have some well-designed API
for this as well.

The real question is what to do on systems that don't use logind. That
will depend on what kind of information is available and how we can
control things. Inevitably this means that we will have a fair amount of
system-specific code in the package.

Best,
Andy

PS:

In trying to understand `unread-command-events' and 'special-event-map'
I came across this bit in bindings.el:

;; FIXME: Do those 3 events really ever reach the global-map ?
;;        It seems that they can't because they're handled via
;;        special-event-map which is used at very low-level.  -stef
(global-set-key [delete-frame] 'handle-delete-frame)
(global-set-key [iconify-frame] 'ignore)
(global-set-key [make-frame-visible] 'ignore)

So I think the answer to the question is "yes, provided someone puts the
event on unread-command-events" where it won't be handled first by
special-event-map. This is why I found that I could inject these special
events onto unread-command-events and have them trigger a callback, but
not the others.

-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06  5:20                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06  5:59                                   ` Andrew Cohen
@ 2025-02-06  7:32                                   ` Andrew Cohen
  2025-02-06 10:54                                   ` Ship Mints
  2 siblings, 0 replies; 55+ messages in thread
From: Andrew Cohen @ 2025-02-06  7:32 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 63620, Eli Zaretskii, michael.albinus, Ship Mints

>>>>> "SM" == Stefan Monnier <monnier@iro.umontreal.ca> writes:

[...]

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

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

Best,
Andy
-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-05 22:37                         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06  1:43                           ` Andrew Cohen
@ 2025-02-06  8:26                           ` Eli Zaretskii
  2025-02-06 11:56                             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 15:29                             ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 2 replies; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-06  8:26 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: acohen, 63620, michael.albinus

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: acohen@ust.hk,  63620@debbugs.gnu.org,  michael.albinus@gmx.de
> Date: Wed, 05 Feb 2025 17:37:20 -0500
> 
> >> 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?
> 
> I don't understand the question:

It seems you understood it well enough to answer it ;-)

>                                  why would those not be ale to run the
> hook?  If it's because it's in a separate UI thread, they can push to
> `pending_funcalls`, or in the worst case they can add an event into the
> event queue and then use `special-event-map` to run an ad-hoc function
> which runs the hook.
> 
> Of course, we could similarly make the D-bus code manually do
> (lookup-key special-event-map [sleep-event])

Thanks, so which of these solutions would you recommend as the
cleanest and the most convenient/extensible one?

Michael, do you have any opinions or comments about these
possibilities, from the D-Bus support POV?





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06  5:20                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06  5:59                                   ` Andrew Cohen
  2025-02-06  7:32                                   ` Andrew Cohen
@ 2025-02-06 10:54                                   ` Ship Mints
  2 siblings, 0 replies; 55+ messages in thread
From: Ship Mints @ 2025-02-06 10:54 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Andrew Cohen, 63620, Eli Zaretskii, michael.albinus

[-- Attachment #1: Type: text/plain, Size: 845 bytes --]

On macOS, the receiver of a "will sleep" notification can delay sleep for
some time. There's also a message when the screen is put to sleep but not
the OS that might have some utility.

On Thu, Feb 6, 2025 at 12:20 AM Stefan Monnier <monnier@iro.umontreal.ca>
wrote:

> > The idea is that you add code to detect the change at the OS level,
> > and then create an event of type sleep-event with an argument of t for
> > sleep and nil for wake.  The lisp package detects the sleep-event and
> > runs the appropriate code.
>
> BTW: I understand what a "wake" event means, but what about
> a "sleep" event?  I mean: how can we receive this event before we wake
> up again?  Or does it mean that we're about to sleep?  If so what do we
> know about when we'll sleep?  Can we influence (e.g. delay) it?
>
>
>         Stefan
>
>

[-- Attachment #2: Type: text/html, Size: 1297 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06  8:26                           ` Eli Zaretskii
@ 2025-02-06 11:56                             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 12:20                               ` Andrew Cohen
  2025-02-06 15:30                               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 15:29                             ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 2 replies; 55+ messages in thread
From: Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-06 11:56 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: acohen, 63620, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 1454 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

Hi Eli,

>>                                  why would those not be ale to run the
>> hook?  If it's because it's in a separate UI thread, they can push to
>> `pending_funcalls`, or in the worst case they can add an event into the
>> event queue and then use `special-event-map` to run an ad-hoc function
>> which runs the hook.
>>
>> Of course, we could similarly make the D-bus code manually do
>> (lookup-key special-event-map [sleep-event])
>
> Thanks, so which of these solutions would you recommend as the
> cleanest and the most convenient/extensible one?
>
> Michael, do you have any opinions or comments about these
> possibilities, from the D-Bus support POV?

I'm against to touch the D-Bus code because of this. Unneeded
dependency.

I've assembled a POC patch (appended), which adds the sleep-event
special event to special-event-map, and which adds a new function
insert-special-event, all on C level. With this, I'm able to eval in the
*scratch* buffer

--8<---------------cut here---------------start------------->8---
(defun sleep-handle-event (event)
  (declare (completion ignore))
  (interactive "e")
  (message "Event arrived: %S" event))

(insert-special-event '(sleep-event t))
--8<---------------cut here---------------end--------------->8---

insert-special-event is not restricted to the sleep-event event, but
shall support all special events, finally.

Comments?

Best regards, Michael.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 3514 bytes --]

diff --git a/src/keyboard.c b/src/keyboard.c
index 2d8c45c05ee..e6539582eea 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4273,6 +4273,7 @@ kbd_buffer_get_event (KBOARD **kbp,
       case CONFIG_CHANGED_EVENT:
       case FOCUS_OUT_EVENT:
       case SELECT_WINDOW_EVENT:
+      case SLEEP_EVENT:
         {
           obj = make_lispy_event (&event->ie);
           kbd_fetch_ptr = next_kbd_event (event);
@@ -7110,6 +7111,9 @@ make_lispy_event (struct input_event *event)
 #endif
 #endif /* USE_FILE_NOTIFY */

+    case SLEEP_EVENT:
+      return Fcons (Qsleep_event, event->arg);
+
     case CONFIG_CHANGED_EVENT:
 	return list3 (Qconfig_changed_event,
 		      event->arg, event->frame_or_window);
@@ -11631,6 +11635,36 @@ DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 1, 0,
 	  ? Qt : Qnil);
 }

+DEFUN ("insert-special-event", Finsert_special_event, Sinsert_special_event,
+       1, 1, 0,
+       doc: /* Insert a special EVENT into the input queue.  */)
+  (Lisp_Object event)
+{
+  /* Check, that it is a special event.  */
+  CHECK_CONS (event);
+  if (NILP (access_keymap
+	    (get_keymap (Vspecial_event_map, 0, 1), event, 0, 0, 1)))
+    signal_error ("Invalid event kind", XCAR (event));
+
+  /* Construct an input event.  */
+  struct input_event ie;
+  EVENT_INIT (ie);
+  ie.kind =
+    /* TODO: Add the other special event kinds.  */
+    (EQ (XCAR (event), Qsleep_event) ? SLEEP_EVENT
+#ifdef HAVE_DBUS
+     : EQ (XCAR (event), Qdbus_event) ? DBUS_EVENT
+#endif
+     : NO_EVENT);
+  ie.frame_or_window = Qnil;
+  ie.arg = CDR (event);
+
+  /* Store it into the input event queue.  */
+  kbd_buffer_store_event (&ie);
+
+  return (Qnil);
+}
+
 /* Reallocate recent_keys copying the recorded keystrokes
    in the right order.  */
 static void
@@ -12803,6 +12837,7 @@ init_while_no_input_ignore_events (void)
 #ifdef THREADS_ENABLED
   events = Fcons (Qthread_event, events);
 #endif
+  events = Fcons (Qsleep_event, events);

   return events;
 }
@@ -12826,6 +12861,7 @@ is_ignored_event (union buffered_input_event *event)
 #ifdef HAVE_DBUS
     case DBUS_EVENT: ignore_event = Qdbus_event; break;
 #endif
+    case SLEEP_EVENT: ignore_event = Qsleep_event; break;
     default: ignore_event = Qnil; break;
     }

@@ -12931,6 +12967,7 @@ syms_of_keyboard (void)
 #endif /* USE_FILE_NOTIFY */

   DEFSYM (Qtouch_end, "touch-end");
+  DEFSYM (Qsleep_event, "sleep-event");

   /* Menu and tool bar item parts.  */
   DEFSYM (QCenable, ":enable");
@@ -13144,6 +13181,7 @@ syms_of_keyboard (void)
   defsubr (&Srecursive_edit);
   defsubr (&Sinternal_track_mouse);
   defsubr (&Sinput_pending_p);
+  defsubr (&Sinsert_special_event);
   defsubr (&Slossage_size);
   defsubr (&Srecent_keys);
   defsubr (&Sthis_command_keys);
@@ -14017,6 +14055,8 @@ keys_of_keyboard (void)
 			    "handle-focus-out");
   initial_define_lispy_key (Vspecial_event_map, "move-frame",
 			    "handle-move-frame");
+  initial_define_lispy_key (Vspecial_event_map, "sleep-event",
+			    "sleep-handle-event");
 }

 /* Mark the pointers in the kboard objects.
diff --git a/src/termhooks.h b/src/termhooks.h
index 0795148f1af..a77ca25e159 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -291,6 +291,9 @@ #define EMACS_TERMHOOKS_H
   , FILE_NOTIFY_EVENT
 #endif

+  /* Sleep/wake event.  */
+  , SLEEP_EVENT
+
   /* Pre-edit text was changed. */
   , PREEDIT_TEXT_EVENT


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 11:56                             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06 12:20                               ` Andrew Cohen
  2025-02-06 12:24                                 ` Ship Mints
                                                   ` (2 more replies)
  2025-02-06 15:30                               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 3 replies; 55+ messages in thread
From: Andrew Cohen @ 2025-02-06 12:20 UTC (permalink / raw)
  To: 63620; +Cc: eliz, michael.albinus, monnier

>>>>> "MA" == Bug reports for GNU Emacs, the Swiss army knife of text editors <Michael> writes:

[...]

    MA> I'm against to touch the D-Bus code because of this. Unneeded
    MA> dependency.

    MA> I've assembled a POC patch (appended), which adds the
    MA> sleep-event special event to special-event-map, and which adds a
    MA> new function insert-special-event, all on C level. With this,
    MA> I'm able to eval in the *scratch* buffer

    MA> (defun sleep-handle-event (event) (declare (completion ignore))
    MA> (interactive "e") (message "Event arrived: %S" event))

    MA> (insert-special-event '(sleep-event t))

    MA> insert-special-event is not restricted to the sleep-event event,
    MA> but shall support all special events, finally.

    MA> Comments?


I personally like this approach (but what do I know?)

I would change the initial special-event-map binding to 'ignore, so that
nothing happens until sleep-wake-mode is activated. My current iteration
installs the handler in the keymap when the mode is activated and
sets it to 'ignore when its disabled.

I think the remaining big question is how to handle inhibiting sleep
until the sleep-wake code is finished. With dbus.el its straightforward
(although I still don't know how to close the file descriptor returned
from the dbus method in lisp; any help?) but I'm not sure what to do
with other systems. Somehow  sleep-wake-mode needs to communicate that
it is OK to release inhibition. I guess one way might be to mimic the
D-Bus method and include a file descriptor in the sleep-event that
blocks sleep until the fd is closed. But this seems kind of contrived.

Best,
Andy
-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 12:20                               ` Andrew Cohen
@ 2025-02-06 12:24                                 ` Ship Mints
  2025-02-06 13:02                                   ` Andrew Cohen
                                                     ` (2 more replies)
  2025-02-06 14:05                                 ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 15:18                                 ` Eli Zaretskii
  2 siblings, 3 replies; 55+ messages in thread
From: Ship Mints @ 2025-02-06 12:24 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, eliz, michael.albinus, monnier

[-- Attachment #1: Type: text/plain, Size: 2136 bytes --]

The API on macOS would expose a pair of C functions to lisp, one would
inhibit sleep, perhaps returning an opaque "cookie", the second to revoke
the inhibition. The same API can be used to prevent macOS from ever
sleeping, if the user wanted that.

On Thu, Feb 6, 2025 at 7:21 AM Andrew Cohen <acohen@ust.hk> wrote:

> >>>>> "MA" == Bug reports for GNU Emacs, the Swiss army knife of text
> editors <Michael> writes:
>
> [...]
>
>     MA> I'm against to touch the D-Bus code because of this. Unneeded
>     MA> dependency.
>
>     MA> I've assembled a POC patch (appended), which adds the
>     MA> sleep-event special event to special-event-map, and which adds a
>     MA> new function insert-special-event, all on C level. With this,
>     MA> I'm able to eval in the *scratch* buffer
>
>     MA> (defun sleep-handle-event (event) (declare (completion ignore))
>     MA> (interactive "e") (message "Event arrived: %S" event))
>
>     MA> (insert-special-event '(sleep-event t))
>
>     MA> insert-special-event is not restricted to the sleep-event event,
>     MA> but shall support all special events, finally.
>
>     MA> Comments?
>
>
> I personally like this approach (but what do I know?)
>
> I would change the initial special-event-map binding to 'ignore, so that
> nothing happens until sleep-wake-mode is activated. My current iteration
> installs the handler in the keymap when the mode is activated and
> sets it to 'ignore when its disabled.
>
> I think the remaining big question is how to handle inhibiting sleep
> until the sleep-wake code is finished. With dbus.el its straightforward
> (although I still don't know how to close the file descriptor returned
> from the dbus method in lisp; any help?) but I'm not sure what to do
> with other systems. Somehow  sleep-wake-mode needs to communicate that
> it is OK to release inhibition. I guess one way might be to mimic the
> D-Bus method and include a file descriptor in the sleep-event that
> blocks sleep until the fd is closed. But this seems kind of contrived.
>
> Best,
> Andy
> --
> Andrew Cohen
>
>
>
>

[-- Attachment #2: Type: text/html, Size: 2743 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 12:24                                 ` Ship Mints
@ 2025-02-06 13:02                                   ` Andrew Cohen
  2025-02-06 13:07                                     ` Ship Mints
  2025-02-06 14:09                                   ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 15:29                                   ` Eli Zaretskii
  2 siblings, 1 reply; 55+ messages in thread
From: Andrew Cohen @ 2025-02-06 13:02 UTC (permalink / raw)
  To: Ship Mints; +Cc: 63620, eliz, michael.albinus, monnier

>>>>> "SM" == Ship Mints <shipmints@gmail.com> writes:

    SM> The API on macOS would expose a pair of C functions to lisp, one
    SM> would inhibit sleep, perhaps returning an opaque "cookie", the
    SM> second to revoke the inhibition. The same API can be used to
    SM> prevent macOS from ever sleeping, if the user wanted that.

Great!

So the idea now is:

Turning on sleep-wake-mode:

0.  If on a system with D-Bus and logind, we register a signal for
PrepareForSleep with a handler that generates a synthetic sleep-event on
state change using Michael's recent insert-special-event.

1. Install 'sleep-event-handler on the special-event-map for
[sleep-event].

'sleep-event-handler will inhibit sleep (with whatever method is
appropriate for the system); run the function sleep-handler-function
which is a defcustom defaulting to running the hooks; release the
inhibition.

2. disabling sleep-wake-mode removes 'sleep-event-handler from the
keymap and replaces it with 'ignore.

(alternatively we could ask each system to expose a lisp function or
variable to turn on and off the generation of sleep-events)

Best,
Andy


-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 13:02                                   ` Andrew Cohen
@ 2025-02-06 13:07                                     ` Ship Mints
  2025-02-06 15:44                                       ` Eli Zaretskii
  0 siblings, 1 reply; 55+ messages in thread
From: Ship Mints @ 2025-02-06 13:07 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, eliz, michael.albinus, monnier

[-- Attachment #1: Type: text/plain, Size: 1455 bytes --]

I prefer using a mode, it seems more idiomatic. Shall this use
cl-defgeneric in sleep-wake-mode that each system can specialize?

On Thu, Feb 6, 2025 at 8:02 AM Andrew Cohen <acohen@ust.hk> wrote:

> >>>>> "SM" == Ship Mints <shipmints@gmail.com> writes:
>
>     SM> The API on macOS would expose a pair of C functions to lisp, one
>     SM> would inhibit sleep, perhaps returning an opaque "cookie", the
>     SM> second to revoke the inhibition. The same API can be used to
>     SM> prevent macOS from ever sleeping, if the user wanted that.
>
> Great!
>
> So the idea now is:
>
> Turning on sleep-wake-mode:
>
> 0.  If on a system with D-Bus and logind, we register a signal for
> PrepareForSleep with a handler that generates a synthetic sleep-event on
> state change using Michael's recent insert-special-event.
>
> 1. Install 'sleep-event-handler on the special-event-map for
> [sleep-event].
>
> 'sleep-event-handler will inhibit sleep (with whatever method is
> appropriate for the system); run the function sleep-handler-function
> which is a defcustom defaulting to running the hooks; release the
> inhibition.
>
> 2. disabling sleep-wake-mode removes 'sleep-event-handler from the
> keymap and replaces it with 'ignore.
>
> (alternatively we could ask each system to expose a lisp function or
> variable to turn on and off the generation of sleep-events)
>
> Best,
> Andy
>
>
> --
> Andrew Cohen
>

[-- Attachment #2: Type: text/html, Size: 2031 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 12:20                               ` Andrew Cohen
  2025-02-06 12:24                                 ` Ship Mints
@ 2025-02-06 14:05                                 ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 15:18                                 ` Eli Zaretskii
  2 siblings, 0 replies; 55+ messages in thread
From: Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-06 14:05 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, eliz, monnier

Andrew Cohen <acohen@ust.hk> writes:

Hi Andrew,

> I would change the initial special-event-map binding to 'ignore, so that
> nothing happens until sleep-wake-mode is activated. My current iteration
> installs the handler in the keymap when the mode is activated and
> sets it to 'ignore when its disabled.

Good idea, I change the patch accordingly.

> I think the remaining big question is how to handle inhibiting sleep
> until the sleep-wake code is finished. With dbus.el its straightforward
> (although I still don't know how to close the file descriptor returned
> from the dbus method in lisp; any help?) but I'm not sure what to do
> with other systems. Somehow  sleep-wake-mode needs to communicate that
> it is OK to release inhibition. I guess one way might be to mimic the
> D-Bus method and include a file descriptor in the sleep-event that
> blocks sleep until the fd is closed. But this seems kind of contrived.

I haven't checked this yet. We will do it once the special-event based
approach is accepted.

> Best,
> Andy

Best regards, Michael.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 12:24                                 ` Ship Mints
  2025-02-06 13:02                                   ` Andrew Cohen
@ 2025-02-06 14:09                                   ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 14:11                                     ` Ship Mints
  2025-02-06 15:29                                   ` Eli Zaretskii
  2 siblings, 1 reply; 55+ messages in thread
From: Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-06 14:09 UTC (permalink / raw)
  To: Ship Mints; +Cc: Andrew Cohen, 63620, eliz, monnier

Ship Mints <shipmints@gmail.com> writes:

Hi Ship,

> The API on macOS would expose a pair of C functions to lisp, one would
> inhibit sleep, perhaps returning an opaque "cookie", the second to
> revoke the inhibition. The same API can be used to prevent macOS from
> ever sleeping, if the user wanted that.

Why that? If we have the special event sleep-event, you can call
kbd_buffer_store_event directly in your C source.

The arguments for the sleep-event can be extended as we like, as API.

Best regards, Michael.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 14:09                                   ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06 14:11                                     ` Ship Mints
  2025-02-06 14:53                                       ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 55+ messages in thread
From: Ship Mints @ 2025-02-06 14:11 UTC (permalink / raw)
  To: Michael Albinus; +Cc: Andrew Cohen, 63620, eliz, monnier

[-- Attachment #1: Type: text/plain, Size: 962 bytes --]

The flow, as I understand it looks like it will be:

1 OS reports about to sleep
2 C code posts an event
3 sleep-wake-mode processes the event
3a Tell the OS to prevent sleep (has to be done in C)
3b Call hooks
3c Tell the OS it's now okay to sleep (ditto in C)

It's 3a and 3c that I was referring to.

On Thu, Feb 6, 2025 at 9:09 AM Michael Albinus <michael.albinus@gmx.de>
wrote:

> Ship Mints <shipmints@gmail.com> writes:
>
> Hi Ship,
>
> > The API on macOS would expose a pair of C functions to lisp, one would
> > inhibit sleep, perhaps returning an opaque "cookie", the second to
> > revoke the inhibition. The same API can be used to prevent macOS from
> > ever sleeping, if the user wanted that.
>
> Why that? If we have the special event sleep-event, you can call
> kbd_buffer_store_event directly in your C source.
>
> The arguments for the sleep-event can be extended as we like, as API.
>
> Best regards, Michael.
>

[-- Attachment #2: Type: text/html, Size: 2006 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 14:11                                     ` Ship Mints
@ 2025-02-06 14:53                                       ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 55+ messages in thread
From: Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-06 14:53 UTC (permalink / raw)
  To: Ship Mints; +Cc: Andrew Cohen, 63620, eliz, monnier

Ship Mints <shipmints@gmail.com> writes:

Hi Ship,

> The flow, as I understand it looks like it will be:
>
> 1 OS reports about to sleep
> 2 C code posts an event
> 3 sleep-wake-mode processes the event
> 3a Tell the OS to prevent sleep (has to be done in C)
> 3b Call hooks
> 3c Tell the OS it's now okay to sleep (ditto in C)
>
> It's 3a and 3c that I was referring to.

Thanks, it wasn't clear to me in your message.

Best regards, Michael.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 12:20                               ` Andrew Cohen
  2025-02-06 12:24                                 ` Ship Mints
  2025-02-06 14:05                                 ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06 15:18                                 ` Eli Zaretskii
  2025-02-06 15:36                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 15:36                                   ` Andrew Cohen
  2 siblings, 2 replies; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-06 15:18 UTC (permalink / raw)
  To: Andrew Cohen; +Cc: 63620, michael.albinus, monnier

> From: Andrew Cohen <acohen@ust.hk>
> Cc: Eli Zaretskii <eliz@gnu.org>,  Michael Albinus <michael.albinus@gmx.de>,
>   63620@debbugs.gnu.org,  Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Thu, 06 Feb 2025 20:20:18 +0800
> 
> I think the remaining big question is how to handle inhibiting sleep
> until the sleep-wake code is finished. With dbus.el its straightforward
> (although I still don't know how to close the file descriptor returned
> from the dbus method in lisp; any help?) but I'm not sure what to do
> with other systems.

What is the semantics of this?  If the user closes the lid of the
laptop, and that was defined to put the system to sleep, does such
"inhibiting" mean the system will not sleep?  If so, I'm not sure this
is supported.  Or do you mean to delay sleep which is triggered by
prolonged enough lack of activity?





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06  8:26                           ` Eli Zaretskii
  2025-02-06 11:56                             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06 15:29                             ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 15:58                               ` Eli Zaretskii
  1 sibling, 1 reply; 55+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-06 15:29 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: acohen, 63620, michael.albinus

> Thanks, so which of these solutions would you recommend as the
> cleanest and the most convenient/extensible one?

For the "wake", we could make it into an event, but for the "sleep" part
we can't really push this to the event queue because we need to process
it promptly (the system is waiting for an answer).

So I'd go with the hook.


        Stefan






^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 12:24                                 ` Ship Mints
  2025-02-06 13:02                                   ` Andrew Cohen
  2025-02-06 14:09                                   ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06 15:29                                   ` Eli Zaretskii
  2025-02-06 15:40                                     ` Ship Mints
  2 siblings, 1 reply; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-06 15:29 UTC (permalink / raw)
  To: Ship Mints; +Cc: acohen, 63620, michael.albinus, monnier

> From: Ship Mints <shipmints@gmail.com>
> Date: Thu, 6 Feb 2025 07:24:37 -0500
> Cc: 63620@debbugs.gnu.org, eliz@gnu.org, michael.albinus@gmx.de, 
> 	monnier@iro.umontreal.ca
> 
> The API on macOS would expose a pair of C functions to lisp, one would inhibit sleep, perhaps returning an
> opaque "cookie", the second to revoke the inhibition.

Why would this have to be exposed to Lisp?  We want to make sure the
system doesn't go to sleep until after the function invoked by the
"about to go to sleep" event completes its job and exits, and for that
all we need is to revoke the inhibition once the function exits, no?





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 11:56                             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 12:20                               ` Andrew Cohen
@ 2025-02-06 15:30                               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 55+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-06 15:30 UTC (permalink / raw)
  To: Michael Albinus; +Cc: acohen, 63620, Eli Zaretskii

> insert-special-event is not restricted to the sleep-event event, but
> shall support all special events, finally.

FWIW, that sounds like a useful primitive.


        Stefan






^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 15:18                                 ` Eli Zaretskii
@ 2025-02-06 15:36                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 15:42                                     ` Ship Mints
  2025-02-06 15:43                                     ` Andrew Cohen
  2025-02-06 15:36                                   ` Andrew Cohen
  1 sibling, 2 replies; 55+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-06 15:36 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Andrew Cohen, 63620, michael.albinus

> What is the semantics of this?  If the user closes the lid of the
> laptop, and that was defined to put the system to sleep, does such
> "inhibiting" mean the system will not sleep?  If so, I'm not sure this
> is supported.

Don't know about "supported", but failing to sleep when the laptop is
closed can be a major problem (I only experienced the milder versions,
like finding my laptop with an empty battery, or my backpack all dirty
with melted chocolate, but overheating can be a serious issue).

[ Of course, it can also be useful, when the laptop is docked into
  a keyboard+screen station, or when you want to use it as a headless
  server.  ]


        Stefan






^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 15:18                                 ` Eli Zaretskii
  2025-02-06 15:36                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06 15:36                                   ` Andrew Cohen
  1 sibling, 0 replies; 55+ messages in thread
From: Andrew Cohen @ 2025-02-06 15:36 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 63620, michael.albinus, monnier

>>>>> "EZ" == Eli Zaretskii <eliz@gnu.org> writes:

[...]

    EZ> What is the semantics of this?  If the user closes the lid of
    EZ> the laptop, and that was defined to put the system to sleep,
    EZ> does such "inhibiting" mean the system will not sleep?  If so,
    EZ> I'm not sure this is supported.  Or do you mean to delay sleep
    EZ> which is triggered by prolonged enough lack of activity?

The former.  Here is how it works for logind (which is common for
gnu/linux desktops):

logind, as part of the desktop system,  takes responsibility for sleep
initiated through the desktop: that is, through a lack of activity, an
explicit hibernate command (maybe a keypress or a menu item) or through
a lid switch, for example. When a sleep request is initiated this way,
it is announced through D-Bus (the PrepareForSleep signal); D-Bus also
has methods that can control the behavior. An "Inhibit" method can be
called which inhibits the sleep process, even if the lid is now closed,
for example. (This inhibition can just be a delay, or it can be a full
block depending on the parameters passed to "Inhibit"); as long as the
block is in place the system will not sleep. The "Inhibit" method
returns a file descriptor, and the block remains in force until the file
descriptor is closed.

It is, of course, possible to trigger hibernation outside of the desktop
system (directly to the kernel, for example), and this is not controlled
through D-Bus.

My daily routine involves a laptop moving from home to office, and I
rarely log out of the desktop or shutdown. So I typically just shut the
lid which triggers hibernation, and rely on sleep-wake-mode to manage
gnus network connections and my vpn. I had never bothered inhibiting the
sleep since Emacs was always fast enough to complete in time, but the
right thing is certainly to call the "Inhibit" method. Other systems are
likely different.

Best,
Andy

-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 15:29                                   ` Eli Zaretskii
@ 2025-02-06 15:40                                     ` Ship Mints
  0 siblings, 0 replies; 55+ messages in thread
From: Ship Mints @ 2025-02-06 15:40 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: acohen, 63620, michael.albinus, monnier

[-- Attachment #1: Type: text/plain, Size: 846 bytes --]

On Thu, Feb 6, 2025 at 10:29 AM Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Ship Mints <shipmints@gmail.com>
> > Date: Thu, 6 Feb 2025 07:24:37 -0500
> > Cc: 63620@debbugs.gnu.org, eliz@gnu.org, michael.albinus@gmx.de,
> >       monnier@iro.umontreal.ca
> >
> > The API on macOS would expose a pair of C functions to lisp, one would
> inhibit sleep, perhaps returning an
> > opaque "cookie", the second to revoke the inhibition.
>
> Why would this have to be exposed to Lisp?  We want to make sure the
> system doesn't go to sleep until after the function invoked by the
> "about to go to sleep" event completes its job and exits, and for that
> all we need is to revoke the inhibition once the function exits, no?
>

That's right. The revocation on macOS requires calling an objective-c API
to relinquish the inhibition.

[-- Attachment #2: Type: text/html, Size: 1676 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 15:36                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06 15:42                                     ` Ship Mints
  2025-02-06 16:06                                       ` Eli Zaretskii
  2025-02-06 15:43                                     ` Andrew Cohen
  1 sibling, 1 reply; 55+ messages in thread
From: Ship Mints @ 2025-02-06 15:42 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Andrew Cohen, 63620, Eli Zaretskii, michael.albinus

[-- Attachment #1: Type: text/plain, Size: 1188 bytes --]

macOS has an annoying feature that will wake the computer periodically to
check shite like email and messages and then go back to sleep. I do not
know if the notifications we're interested in are invoked by this default
behavior. I've disabled mine to avoid burning the battery with the lid
closed.

On Thu, Feb 6, 2025 at 10:37 AM Stefan Monnier via Bug reports for GNU
Emacs, the Swiss army knife of text editors <bug-gnu-emacs@gnu.org> wrote:

> > What is the semantics of this?  If the user closes the lid of the
> > laptop, and that was defined to put the system to sleep, does such
> > "inhibiting" mean the system will not sleep?  If so, I'm not sure this
> > is supported.
>
> Don't know about "supported", but failing to sleep when the laptop is
> closed can be a major problem (I only experienced the milder versions,
> like finding my laptop with an empty battery, or my backpack all dirty
> with melted chocolate, but overheating can be a serious issue).
>
> [ Of course, it can also be useful, when the laptop is docked into
>   a keyboard+screen station, or when you want to use it as a headless
>   server.  ]
>
>
>         Stefan
>
>
>
>
>

[-- Attachment #2: Type: text/html, Size: 1648 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 15:36                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-02-06 15:42                                     ` Ship Mints
@ 2025-02-06 15:43                                     ` Andrew Cohen
  1 sibling, 0 replies; 55+ messages in thread
From: Andrew Cohen @ 2025-02-06 15:43 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 63620, Eli Zaretskii, michael.albinus

>>>>> "SM" == Stefan Monnier <monnier@iro.umontreal.ca> writes:

    >> What is the semantics of this?  If the user closes the lid of the
    >> laptop, and that was defined to put the system to sleep, does
    >> such "inhibiting" mean the system will not sleep?  If so, I'm not
    >> sure this is supported.

    SM> Don't know about "supported", but failing to sleep when the
    SM> laptop is closed can be a major problem (I only experienced the
    SM> milder versions, like finding my laptop with an empty battery,
    SM> or my backpack all dirty with melted chocolate, but overheating
    SM> can be a serious issue).

The "Inhibit" method I am using allows a delay rather than a total
block. You can specify a time (default I think is 5 seconds) after which
the sleep will proceed (or you can remove the delay earlier). So your
chocolate is safe (at least from melting).


-- 
Andrew Cohen





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 13:07                                     ` Ship Mints
@ 2025-02-06 15:44                                       ` Eli Zaretskii
  2025-02-06 15:45                                         ` Ship Mints
  0 siblings, 1 reply; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-06 15:44 UTC (permalink / raw)
  To: Ship Mints; +Cc: acohen, 63620, michael.albinus, monnier

> From: Ship Mints <shipmints@gmail.com>
> Date: Thu, 6 Feb 2025 08:07:44 -0500
> Cc: 63620@debbugs.gnu.org, eliz@gnu.org, michael.albinus@gmx.de, 
> 	monnier@iro.umontreal.ca
> 
> I prefer using a mode, it seems more idiomatic. Shall this use cl-defgeneric in sleep-wake-mode that each
> system can specialize?

Are there differences on the Lisp level between the systems?





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 15:44                                       ` Eli Zaretskii
@ 2025-02-06 15:45                                         ` Ship Mints
  0 siblings, 0 replies; 55+ messages in thread
From: Ship Mints @ 2025-02-06 15:45 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: acohen, 63620, michael.albinus, monnier

[-- Attachment #1: Type: text/plain, Size: 1117 bytes --]

Only insofar as the C-level API calls are different and that the mechanism
may have an impedance mismatches. For example, I do not think on macOS
there is a way to describe a delay as Andrew suggests there is on
dbus/logind/systemd. The only API I'm aware of is one where you tell the OS
that the "user is busy" and then tell it the user is not busy. However, the
documentation for the "will sleep" notification does say one can delay in
the handler but is otherwise silent on how to do that and I've found no
information. I'll have to contact Apple to see how to do this, if it's
real. It could be vestigial documentation.

On Thu, Feb 6, 2025 at 10:44 AM Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Ship Mints <shipmints@gmail.com>
> > Date: Thu, 6 Feb 2025 08:07:44 -0500
> > Cc: 63620@debbugs.gnu.org, eliz@gnu.org, michael.albinus@gmx.de,
> >       monnier@iro.umontreal.ca
> >
> > I prefer using a mode, it seems more idiomatic. Shall this use
> cl-defgeneric in sleep-wake-mode that each
> > system can specialize?
>
> Are there differences on the Lisp level between the systems?
>

[-- Attachment #2: Type: text/html, Size: 1833 bytes --]

^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 15:29                             ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06 15:58                               ` Eli Zaretskii
  0 siblings, 0 replies; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-06 15:58 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: acohen, 63620, michael.albinus

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: acohen@ust.hk,  63620@debbugs.gnu.org,  michael.albinus@gmx.de
> Date: Thu, 06 Feb 2025 10:29:27 -0500
> 
> > Thanks, so which of these solutions would you recommend as the
> > cleanest and the most convenient/extensible one?
> 
> For the "wake", we could make it into an event, but for the "sleep" part
> we can't really push this to the event queue because we need to process
> it promptly (the system is waiting for an answer).

AFAIK, this is not a problem, because the system will wait for
programs to become idle anyway.





^ permalink raw reply	[flat|nested] 55+ messages in thread

* bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake
  2025-02-06 15:42                                     ` Ship Mints
@ 2025-02-06 16:06                                       ` Eli Zaretskii
  0 siblings, 0 replies; 55+ messages in thread
From: Eli Zaretskii @ 2025-02-06 16:06 UTC (permalink / raw)
  To: Ship Mints; +Cc: acohen, 63620, michael.albinus, monnier

> From: Ship Mints <shipmints@gmail.com>
> Date: Thu, 6 Feb 2025 10:42:02 -0500
> Cc: Eli Zaretskii <eliz@gnu.org>, Andrew Cohen <acohen@ust.hk>, 63620@debbugs.gnu.org, 
> 	michael.albinus@gmx.de
> 
> macOS has an annoying feature that will wake the computer periodically to check shite like email and
> messages and then go back to sleep. I do not know if the notifications we're interested in are invoked by this
> default behavior. I've disabled mine to avoid burning the battery with the lid closed.

If the system wakes from sleep, it shouldn't matter to Emacs why it
wakes.  If it then goes back to sleep, the sleep handler will be
reinvoked; if it doesn't, it won't.

So I'm not sure we should worry about this.  If the user doesn't want
his/her system to be awoken by these conditions, he/she should
configure the system appropriately, like you did.





^ permalink raw reply	[flat|nested] 55+ messages in thread

end of thread, other threads:[~2025-02-06 16:06 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-20 23:19 bug#63620: 30.0.50; [Feature Request] run hooks on sleep/wake Andrew Cohen
2023-05-21  8:12 ` Michael Albinus
2023-06-05 13:06   ` Andrew Cohen
2023-06-10 10:47     ` Michael Albinus
2025-02-04  3:19       ` Andrew Cohen
2025-02-04 13:16         ` Eli Zaretskii
2025-02-04 13:38           ` Andrew Cohen
2025-02-04 14:49             ` Eli Zaretskii
2025-02-05 12:51               ` Andrew Cohen
2025-02-05 13:27                 ` Andrew Cohen
2025-02-05 15:28                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-05 18:21                     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-05 20:21                       ` Eli Zaretskii
2025-02-05 22:37                         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06  1:43                           ` Andrew Cohen
2025-02-06  2:06                             ` Ship Mints
2025-02-06  2:20                               ` Andrew Cohen
2025-02-06  2:26                                 ` Ship Mints
2025-02-06  5:20                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06  5:59                                   ` Andrew Cohen
2025-02-06  7:32                                   ` Andrew Cohen
2025-02-06 10:54                                   ` Ship Mints
2025-02-06  8:26                           ` Eli Zaretskii
2025-02-06 11:56                             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06 12:20                               ` Andrew Cohen
2025-02-06 12:24                                 ` Ship Mints
2025-02-06 13:02                                   ` Andrew Cohen
2025-02-06 13:07                                     ` Ship Mints
2025-02-06 15:44                                       ` Eli Zaretskii
2025-02-06 15:45                                         ` Ship Mints
2025-02-06 14:09                                   ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06 14:11                                     ` Ship Mints
2025-02-06 14:53                                       ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06 15:29                                   ` Eli Zaretskii
2025-02-06 15:40                                     ` Ship Mints
2025-02-06 14:05                                 ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06 15:18                                 ` Eli Zaretskii
2025-02-06 15:36                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06 15:42                                     ` Ship Mints
2025-02-06 16:06                                       ` Eli Zaretskii
2025-02-06 15:43                                     ` Andrew Cohen
2025-02-06 15:36                                   ` Andrew Cohen
2025-02-06 15:30                               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06 15:29                             ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06 15:58                               ` Eli Zaretskii
2025-02-04 14:55             ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-04 15:21               ` Ship Mints
2025-02-04 15:30                 ` Eli Zaretskii
2025-02-04 15:35                   ` Ship Mints
2025-02-04 15:42                     ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-04 15:51                       ` Ship Mints
2025-02-04 16:15                         ` Eli Zaretskii
2025-02-04 16:12                     ` Eli Zaretskii
2025-02-04 15:38                   ` Michael Albinus via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-04 18:14                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.