process-next-event
is responsible for reading port-specific messages
and constructing events based on that. When CLIM event is created,
distribute-event
is called on the port and the event itself.
Then event is dispatched to a target sheet. For instance:
standard-sheet-input-mixin
- event is queued
immediate-sheet-input-mixin
- event is handled
Distributing an event may result in dispatching its copy to another sheet instead. For example when there is a grabbed sheet, the pointer events are unconditionally dispatched to the grabbed sheet instead of the original target.
process-next-event port &key wait-function timeout [gf] This function provides a standard interface for one pass through a port's event processing loop. wait-function is either nil or a function of no arguments that acts as a predicate; it has dynamic extent. The predicate should wait until one of three conditions occurs: [NOTE] In this description, "the predicate" seems to sometimes refer to the wait function and sometimes to process-next-event itself. Perhaps someone could rephrase this description in a way that I can make sense of it. -- Robert Strandh 2005-04-30 If an event if received and processed, the predicate should return true. [NOTE] The second "if" should be "is" -- David 2009-03-22 If a timeout occurs, the predicate should return false. [annotate] If the wait function returns true, the predicate should return the two values false and :timeout. [NOTE] This is all jumbled up. it should be: * If an event is received and processed, the predicate should return true. * If a timeout occurs, the process-next-event should return the two values false and :timeout. * If the wait function returns true, the predicate should return the two values false and :wait-function. Also to avoid busy looping it should be specified, that wait-function may be called only after certain port events occur (not necessarily "CLIM events"). -- Daniel Kochmanski 2019-03-26 A port implementation must provide a method for this function that reads the next window server-specific device event, blocking if necessary, and then invokes the event distributor. [annotate]
process-next-event port &key wait-function timeout [gf] This function provides a standard interface for one pass through a port's event processing loop. The function should wait until one of three conditions occurs: - If an event is received and processed it should return true. - If wait-function returns true, process-next-event should return the two values: false and :wait-function. - If a timeout occurs, process-next-event should return the two values: false and :timeout. wait-function is either nil or a function with no arguments that acts as a predicate; it has dynamic extent and it doesn't block. It should return true if there is no further need for processing the next event. The predicate is invoked by the port-specific method on this generic function at least before trying to read an event and again, after the timeout, if it has been reached. wait-function may be called multiple times while the process-next-event method tries to read the next event. timeout is either nil (then process-next-event waits indefinetely for the next event) or a time delay specified in seconds after which the function gives up. In that case if wait-function returns true the second value returned is :wait-function, otherwise it is :timeout.
“Predicate [wait-function] is invoked by the port before trying to read an event and after the timeout.”
port may have a blocking IO and wait-function
in principle may
depend on something asynchronous. In that case we can’t assure
immediate return of the process-next-event
. That’s why it is
important to clarify that it is called before trying to read the
event.
- Why before (and not after)? Because condition may be already met and sourcing next event may be a lengthy operation.
- Why do it after a timeout? Because we are more interested in a success than a failure. “Wait condition” met is a success path.
- Why “trying to read an event” not “reading an event”? Because
not all messages processed by a port are distributed as
CLIM
events. For instancexlib:process-event
may call our handler with a:mapping-notify
- it doesn’t result in distributing an event henceprocess-next-event
won’t meet the first condition. We take the opportunity and call await-function
to see if we can return anyway.