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
CLIMevents. For instancexlib:process-eventmay call our handler with a:mapping-notify- it doesn’t result in distributing an event henceprocess-next-eventwon’t meet the first condition. We take the opportunity and call await-functionto see if we can return anyway.