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

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

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

> Pip Cet <[email-masked]> writes:
>
>> "Daniel Colascione" <[email-masked]> writes:
>>
>>> On June 10, 2025 10:40:39 AM PDT, Pip Cet <[email-masked]> wrote:
>>>>"Stefan Monnier" <[email-masked]> writes:
>>>>
>>>>>> BTW: the problem isn't just with transient. It also manifests with
>>>>>> read-extended-command! It's a nasty race that, AFAICT, has been with us
>>>>>> since the 90s. I think defining read_char to translate quits to quit_char
>>>>>> solves the problem.
>>>>>
>>>>> I like your way of thinking.  I'm not completely sure it will solve
>>>>> world hunger, and it may come with regressions, but it's worth a try.
>>>>
>>>>I must be missing something: read_char translates quits to quit_char if
>>>>called with inhibit-quit bound to t, and never returns with quit-flag
>>>>set to t in that case.
>>>
>>> You shouldn't have to call it with inhibit-quit for it do that. It should just happen all the time.
>>
>> But we don't usually want read-event to eat quits and report them by
>> returning quit_char.  The old behavior gave me a choice.
>
> You still have a choice.  You can signal quit if you get a quit event.

Making

(while t (read-event))

infloop without being able to quit is a bad idea.  We shouldn't do it.

>> (while t (read-event))
>>
>> on your branch appears to hang the Emacs session unquittably (even
>> SIGUSR2 doesn't seem to work).  It should permit quits, because that
>> code says nothing about wanting quits to be reported.
>
> By calling read-event, you're asking Emacs read an event.  C-g is an
> event.

It's not an ordinary event. It's an event that should be handled
specially, which is what we do now and should continue doing. There's a
way around that, but the vast majority of callers don't need to worry
about it: (read-event) should read an ordinary event and return it,
without breaking quit.

> Lisp isn't saying
> read-event-unless-it's-C-g-in-which-case-exit-non-locally.  Lisp says
> read-event.

That's implicit as for any other Lisp command that isn't specifically
documented not to quit.  (As, for example, read-key-sequence is).

>> Anyway, here are the minor changes to keyboard.c to avoid the original
>> problem (the third change is somewhat independent and avoids quitting in
>> kbd_buffer_get_event):
>
> This change papers over the problem of ambiguous C-g representation

It doesn't paper over anything.  It merely quits before dequeueing
events when throw-on-input is in effect, without any major changes.

> without trying to fix it or address the even worse problem of the quits
> going to the event loop and not being looked up as commands.

Are you saying quits should *generally* be treated as commands rather
than by the event loop?  Because my opinion is precisely the opposite:
quits should always be handled by C code, never by keyboard-quit,
because that's what they are used for: to break out of misbehaving Lisp
code, with minimal involvement of Lisp machinery which may be
misbehaving.

We'd need new, incompatible versions of almost all callers, because
those do want to quit when we hit C-g.  And, again, we're taking away
the choice "act on C-g as usual", replacing it by a new "identify
(somehow) quit events and (somehow) quit when you see one".

Pip