An answer to another question suggests that supplying a timeout of 0.0 to
read-event (as the
SECONDS parameter) will always return
nil immediately, and, if I'm reading the code in
keyboard.c correctly, even a (very) very small non-zero timeout could return
checking everywhere for an existing event.
input-pending-p can return false positives, calling
read-event with a non-zero value for
SECONDS to try to get that (nonexistant event) could cause a delay and still return
Practically, it seems like using a millisecond or two for
SECONDS should be fine, but it does feel
less tidy than if
read-event returned any available events even with a timout of 0.0.
Short of a locall Emacs build, is there a solution a particularly particular user might prefer?
The code @phils gave with his answer demonstrates this is not correct if "unread" events are
available in any of 3 queues. I've added code that suggests yet another event-queue is checked by
input-pending-p that is skipped by
SECONDS is 0.0.
My polling loop below is more complicated than I'd like, but I wanted to record all the relative event times. The quit key (C-g) will terminate.
The code starts calling
read-event with a
SECONDS value of 0.0, increasing it after 5 seconds.
It records when
input-pending-p first returns true, and then the time and
SECONDS value when
read-event first returns non-nil.
For me, pressing a key before 5 seconds is up demonstrates that
input-pending-p can be true, but
SECONDS is increased to at least a little above 0.0,
read-event consistently returns
(let* ((input-at) (read-at) (wait-to-try 0.0) (deadline (+ (float-time) 5.0)) (past-due)) (while 't (setq past-due (- (float-time) deadline)) (when (and (not input-at) (input-pending-p)) (setq input-at past-due)) (when (not read-at) (when (> past-due 0.0) (setq wait-to-try (* 0.001 past-due))) (when (read-event nil nil wait-to-try) (setq read-at past-due))) (message "past: %f in-p: %s in-at: %s wait: %s read-at %s" past-due (input-pending-p) input-at wait-to-try read-at) (redisplay)))