Skip to content

Instantly share code, notes, and snippets.

@dkochmanski
Last active January 22, 2020 10:32
Show Gist options
  • Save dkochmanski/81de19e16b8637ba0a7a39a2012d1f05 to your computer and use it in GitHub Desktop.
Save dkochmanski/81de19e16b8637ba0a7a39a2012d1f05 to your computer and use it in GitHub Desktop.
process-next-event

process-next-event

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.

Annotated definition in the spec

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]

Proposed clarification

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.

Discussion

“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 instance xlib:process-event may call our handler with a :mapping-notify - it doesn’t result in distributing an event hence process-next-event won’t meet the first condition. We take the opportunity and call a wait-function to see if we can return anyway.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment