Subject: Re: bug#78737: sit-for behavior changes when byte-compiled

From: Pip Cet <[email-masked]>
Date: Wed, 11 Jun 2025 15:19:07 +0000

"Daniel Colascione" <[email-masked]> writes:

> Eli Zaretskii <[email-masked]> writes:
>
>> We could also leave the old behavior alone.  It isn't bad behavior.
>
> So you're saying it's a good thing that the behavior of the code changes
> depending on whether it's compiled?  You're right: that's not bad
> behavior.  It's abysmal behavior.

Fixing the sit-for bug does not in any way require breaking quit.

We should decide how we want to fix this bug, independently of
considering major changes to the quitting mechanism in general.

Binding inhibit-quit works; not removing events from the queue when
we're about to quit works; re-queueing events from C would work, even
though we'd need an extra flag to know how to requeue them so it'd be an
API change.

What would work best, IMHO, is a non-destructive way to wait for the
next event.

My suggestion would be:

    (while-no-input (sleep-for seconds))

That doesn't currently work in nested while-no-input because
while-no-input nests the wrong way around (the outermost while-no-input
should win, not the innermost one), but that's trivial to fix.

diff --git a/lisp/subr.el b/lisp/subr.el
index 729f8b3e09b..56575259ff9 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3696,28 +3696,9 @@ sit-for
     (or nodisp (redisplay)))
    (t
     (or nodisp (redisplay))
-    ;; FIXME: we should not read-event here at all, because it's much too
-    ;; difficult to reliably "undo" a read-event by pushing it onto
-    ;; unread-command-events.
-    ;; For bug#14782, we need read-event to do the keyboard-coding-system
-    ;; decoding (hence non-nil as second arg under POSIX ttys).
-    ;; For bug#15614, we need read-event not to inherit-input-method.
-    ;; So we temporarily suspend input-method-function.
-    (let ((read (let ((input-method-function nil))
-                  (read-event nil t seconds))))
-      (or (null read)
-	  (progn
-            ;; https://lists.gnu.org/r/emacs-devel/2006-10/msg00394.html
-            ;; We want `read' appear in the next command's this-command-event
-            ;; but not in the current one.
-            ;; By pushing (cons t read), we indicate that `read' has not
-            ;; yet been recorded in this-command-keys, so it will be recorded
-            ;; next time it's read.
-            ;; And indeed the `seconds' argument to read-event correctly
-            ;; prevented recording this event in the current command's
-            ;; this-command-keys.
-	    (push (cons t read) unread-command-events)
-	    nil))))))
+    (not (if throw-on-input
+             (sleep-for seconds)
+           (while-no-input (sleep-for seconds)))))))
 
 (defun goto-char--read-natnum-interactive (prompt)
   "Get a natural number argument, optionally prompting with PROMPT.

This appears to fix the original bug and the FIXME without any C
changes, though we might have to hack sleep-for to prevent the hourglass
from showing.

Pip