Subject: bug#31692: Emacs sometimes drops key events

From: Stefan Monnier <[email-masked]>
Date: Thu, 07 Jun 2018 11:30:58 -0400

> @@ -3511,9 +3511,25 @@
>    (let ((catch-sym (make-symbol "input")))
>      `(with-local-quit
>         (catch ',catch-sym
> -	 (let ((throw-on-input ',catch-sym))
> -	   (or (input-pending-p)
> -	       (progn ,@body)))))))
> +	 (let ((throw-on-input ',catch-sym)
> +               val)
> +           (setq val
> +	         (or (input-pending-p)
> +	             (progn ,@body)))
> +           (cond
> +            ;; If quit-flag is equal to throw-on-input, it means BODY
> +            ;; didn't test quit-flag, and therefore ran to completion
> +            ;; even though input arrived before it finished.  In that
> +            ;; case, we must throw manually, because otherwise
> +            ;; quit-flag will remain set, and we get Quit to
> +            ;; top-level, which has undesirable consequences, such as
> +            ;; discarding input etc.
> +            ((eq quit-flag throw-on-input)
> +             (throw 'throw-on-input t))
> +            ;; This is in case the user actually quits while BODY runs.
> +            (quit-flag
> +             nil)
> +            (t val)))))))

I don't understand the (throw 'throw-on-input t)
(throw throw-on-input t) would make more sense, but in any case we're
just about to exit that `catch` so throwing won't have any real effect.
I think instead of (throw 'throw-on-input t) what is needed here is

    (setq quit-flag nil)

which will also make the body return nil (rather than t like (throw
throw-on-input t) would), which I believe is also the right thing.

        Stefan