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

From: Daniel Colascione <[email-masked]>
Date: Tue, 10 Jun 2025 12:46:19 -0700

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.

 I don't think it should do that, it doesn't
>match the quit-flag documentation, but it is what happens right now.  Do
>we really need a new function which is precisely equivalent to
>
>(let ((inhibit-quit t)) (read-event ...)) ?
>
>As for throw-on-input, I don't know what Daniel is proposing to do to
>handle it.  Is every caller of read-event supposed to check
>throw-on-input and simulate it?  How is that better than looking at
>quit-flag, or simply keeping inhibit-quit bound for the critical
>section?

See the fix in the fix i mentioned a message ago. Now the read event functions detect that they're in a context in which quitting is inevitable and try to save the event before control even gets to Lisp. Should be transparent change.

>As for peeking at events, the easiest way seems to me to be to let-bind
>unread-command-events to nil around a call to read-event.  That'll make
>it ignore them, read the next event, which you can then append to
>unread-command-events or not depending on whether you want the command
>loop to handle it.

Isn't unread command events kind of lossy and not something we want to use all the time?

>> Given the pervasive impact, it might be best to have a global config var
>> to enable/disable it (with some scary internal name) until we're
>> confident that it's an improvement.

Changes seem pretty safe. I did add kill switch for inhibiting quit in redisplay.

>I agree it would make sense to separate inhibit-quit meaning "inhibit
>acting on the quit flag" and inhibit-quit meaning "inhibit setting the
>quit flag", but that seems a minor change.

We have a lot of code that makes subtle assumptions about the meaning of the quit flag. I wouldn't change it lightly. The more local changes on my branch seem sufficient.