CLIM mail archive


Problem using Handle-event

   Date: Fri, 08 Jul 94 10:10:33 -0400

     >From: Scott McKay <>
     >For CLIM stream panes, I think you can probably safely wrap an :AROUND
     >method on the CLIM-INTERNALS::RECEIVE-GESTURE method.


     Surely Martin did The Right Thing; i.e. he followed the event protocol as
     outlined by any reasonable reading of the documentation.  But as he
     discovered, this simply doesn't work.  ...

   Indeed, I was a little worried about using a function that was not
   exported from the CLIM-INTERNALS package to do what I took to be the
   job of a function that was exported from the CLIM package.  As Scott
   suggested, it did pretty much the right thing, but I seemed to get
   four copies of every event instead of no copies of most events.

   At this point I went back to the language specifications (I was using
   the User Manual), and could not find HANDLE-EVENT documented there.
   Indeed, the specification do not say much of anything about events.
   On the other hand, the specification did say a lot about streams, and,
   it turns out, what I really wanted to do (process the characters typed
   at the keyboard separately from I/O from other sources) was well
   supported.  There is a function STREAM-READ-CHAR that returns the
   characters typed onto the stream.  Using this function on the stream
   that has the input focus reads characters and nothing but character.
   I did not have to deal with the low level functionality.

BTW, if you specialize STREAM-READ-GESTURE, you will see the mouse
click events, too.

   One other problem arose though.  We also need to read commands, and
   there seemed to be no non-blocking way to do this.  We were back to
   the starting point.  The system would need to wait until a command was
   read before it could go on processing input from other sources.  There
   also turned out to be a simple fix for this problem.  We simply
   specialized the READ-FRAME-COMMAND so that it times out after a
   second.  The following function is the one we wrote to test this
   hypothesis.  In real life, we will want to use READ-COMMAND instead of
   ACCEPT, and we will want to process out character I/O in the body of
   the default top level rather than in READ-FRAME-COMMAND, but it shows
   how the thing worked for us.

   (defmethod CLIM:READ-FRAME-COMMAND ((frame graphics-interface) &key stream)
     (MP:with-timeout (1)
       (if (CLIM:stream-peek-char stream)
	   (format (CLIM:get-frame-pane CLIM:*application-frame* 'display)
		   "<event ~s>~%" (stream-read-char stream))
	 (CLIM:accept 'CLIM:command :stream stream))))

CLIM's high-level input primitive, READ-GESTURE, supports timeouts.  I
wonder if we should introduce a way to have a default timeout for all
of these things, such as introducing a global *INPUT-WAIT-TIMEOUT*.
Then you could simply bind this in your READ-FRAME-COMMAND method.

BTW, you should use (read-command (frame-command-table frame) :stream stream)
in your method instead of calling ACCEPT directly.  It's likely to
work better.

   We learned two lessons from this experience.  First, if we need to do
   something simple (i.e. process the character input separately) there
   is usually a high level way to do it.  If we find ourselves wondering
   about the low level details, we probably missed something.  
I have to agree with this.

   the language specification is a better source of information about the
   language than is the user manual.  My only regret regarding this
   second lesson is that my copy of the specification has no index.

The spec is far more complete.  At least for the Symbolics book, my
goal in the User Manual was to document the most useful functionality.
There just aren't enough hours to do everything.


Main Index | Thread Index