Here is how X11 events are dispatched in XToolkit (roughly):
1. Event is received in XToolkit.run() with XlibWrapper.XNextEvent()
2. Event's data is stored in XAnyEvent class, which contains the following fields: type, serial, send_event, display, window
3. Depending of the event's type a new event is constructed with XToolkit.createEvent(). This method gets pData from the event passed as an argument and creates an instance of subclass of IXAnyEvent, for example, XMapEvent, XConfigureEvent or XReparentEvent
4. Given the new event, we get its's window with event.get_window() method, found a corresponding peer and dispatch event to it
The problem here is that some of the events (XReparentEvent, XGravityEvent and others) have another order of fields than XAnyEvent. Here is the fields of XReparentEvent: type, serial, send_event, display, event, window, ... Thus, the methods get_window() of XAnyEvent and get_event() of XReparentEvent really return the same value. Also, get_window() of XAnyEvent and get_window() of XReparentEvent may return different windows. XReparentEvent should be dispatched to its 'event' member, but now it is dispatched to its 'window' member which may differ from 'event'.
One particular usage of XReparentEvent that is broken is XEmbed server-side support. In XEmbedCanvasPeer we wait for XReparentEvent and get its 'window' method to find an XEmbed client (child window). However, this XReparentEvent is never dispatched to XEmbedCanvasPeer, and so XEmbed server-side support is completely broken.
Posted Date : 2006-12-07 11:15:08.0
For the source of the problem see the bug's description.
Posted Date : 2006-12-07 11:16:19.0
The problem in the bug is caused by the fact that we use IXAnyEvent interface
which is implemented by all events we have. But it is the only reason why it is
implemented is that all those events have fields with appropriate names (such as
window). But the problem is that for some of them (e.g. XReparentEvent)
get_window() will return not the same as we expect from XAnyEvent (which is
supposed to be used for choosing the target for the event.
Here is and description of these structures:
So, to fix the problem I've removed IXAnyEvent, but add correct
description of XEvent and use it everywhere we used IXAnyEvent before. Also during
reviewing our event dispatching code I decided that it would be better to use
XEvent instead of native pointer.
Posted Date : 2007-01-15 09:03:05.0