[comp.windows.x] button press/release race condition, lost events

garya@stan.com (Gary Aitken) (11/15/88)

Having just wasted (?) a lot of time chasing down the source for lost
button press events, I thought the following might save people some trouble.

There are several race conditions caused by the client/server model which
essentially require that button press/release events always be selected
together.  Consider the following:

  Client                              Server
  -----------------------------       ---------------------------
  Select input on ButtonPress
                                      User presses button
                                      Dispatch press to user
  Receive button press
  Grab pointer selecting input on
    ButtonRelease & other stuff
    (e.g. ButtonMotion)
                                      Process Grab
                                      User releases button
                                      Dispatch release to user.
                                      User presses button again.
                              ***     Discarded, pointer still grabbed and
                                        ButtonPress not selected.
  Receive button release.
  Ungrab pointer
                                      Process Ungrab
                                      User releases button
                                      Dispatch release to user.
  Receive 2nd release, but no
    matching press.

The above scenerio has lots of variations.  The grab is not necessary,
but illustrates a common paradigm.  The important lesson is that, if an
application is interested in ButtonPress/ButtonRelease pairs, it should
always select for both of them, to prevent the server from discarding 
events due to timing problems.  The events will be delivered in order,
but the client should probably check for extraneous ones anyway.
In the above example, the initial input selection should be for both
ButtonPress and ButtonRelease.

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (11/20/88)

    Client                              Server
    -----------------------------       ---------------------------
    Select input on ButtonPress
                                        User presses button
                                        Dispatch press to user
    Receive button press
    Grab pointer selecting input on
      ButtonRelease & other stuff
      (e.g. ButtonMotion)
                                        Process Grab
                                        User releases button
                                        Dispatch release to user.
                                        User presses button again.
                                ***     Discarded, pointer still grabbed and
                                          ButtonPress not selected.
    Receive button release.
    Ungrab pointer
                                        Process Ungrab
                                        User releases button
                                        Dispatch release to user.
    Receive 2nd release, but no
      matching press.

    The grab is not necessary, but illustrates a common paradigm.

The grab is necessary to get the kind of error you describe.  Otherwise,
the button press would have caused a grab, the event mask would not have
changed, and the grab would have been release automatically when the button
was released.  Alternatively, your bug is that you aren't using synchronous
event processing during the grab; if you had, then you would have been in a
position to release the grab before the subsequent button press was processed.