emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: address@hidden: Lingering input pending with motif menu bar]


From: Chong Yidong
Subject: Re: address@hidden: Lingering input pending with motif menu bar]
Date: Tue, 04 Jul 2006 20:06:24 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

Richard Stallman <address@hidden> writes:

>     I've found a Lisp-level workaround --- by using `read-event' and
>     `with-timeout', it's possible to catch just the events we are
>     interested in (i.e., mouse clicks and keystrokes).  It took quite a
>     long time to find something that works, though.
>
>     If this is an acceptable solution, the Elisp manual node on "Waiting"
>     could be updated to mention this hack.
>
> If this is the right way to wait N seconds, we should make sit-for do
> this, so that user programs don't have to use a complex work-around.
>
> If this indeed works right, then I think putting this into sit-for
> is a clear bug-fix.  Would you like to do it?

The trouble is that sit-for is widely-used in the Emacs sources,
particularly (sit-for 0) for forcing redisplay.  There is apparently a
need for a routine that waits for a set time, and stops if and only if
there is an Emacs Lisp input event available, which is not an exact
match for what `sit-for' does.  So how about putting this macro into
timer.el?  We can change individual existing `sit-for' calls to use
this if necessary (e.g. in Hanoi), and avoid destabilizing the tree at
this stage of the release.

Another point is that it relies on the timer.el code, and is thus more
heavyweight than sit-for, which is a built-in.  So it can't replace
sit-for generally.

Yes, I've checked that this gets interrupted by input events like
mouse wheel turns, etc: basically, anything that read-event would
grab.  It does not get interrupted by moving the mouse over a toolbar
button, unlike sit-for.


(defmacro wait-for-input (seconds)
  "Wait for SECONDS seconds or until an input event is available.
Value is t if the full time elapsed with no input arriving, and
nil otherwise.

SECONDS may be a floating-point value, meaning that you can wait
for a fraction of a second.  (Not all operating systems support
waiting for a fraction of a second.)

If an input event arrives, it is put in `unread-command-events'.

Unlike `sit-for', this returns nil if and only if an input event
is available.  It does not perform redisplay."
  `(let ((tag (cons nil nil))
         (with-timeout-timers with-timeout-timers)
         event timer)
     (if (catch tag
           (progn
             (setq timer (run-with-timer ,seconds nil
                                         'with-timeout-handler
                                         tag))
             (push timer with-timeout-timers)
             (setq event (read-event))
             nil))
         t
       (cancel-timer timer)
       (push event unread-command-events)
       nil)))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]