Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net --- v1: first implemetation. v2: rework. update merge_events(). v3: delete the incorrect description. v4: MERGE_FLUSH enumeration change. v5: update merge_events() more. fix GenericEvent processing.
The current process_events() pseudecode for non-mergeable events may be simplified as follows:
process_events() { prev_event.type = 0;
while (XCheckIfEvent( &event )) { if (XFilterEvent( &event )) continue;
if (prev_event.type) call_event_handler( &prev_event );
prev_event = event; }
if (prev_event.type) call_event_handler( &prev_event ); }
- "xim preedit callbacks" are called from within the XFilterEvent(). - Depending on the XCheckIfEvent(), XFilterEvent() return value, the call_event_handler() may be called after one or more loop steps.
So, call_event_handler() may be delayed after the next "xim preedit callback" call.
dlls/winex11.drv/event.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 900f24c4002..bee37f3368b 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -263,6 +263,7 @@ enum event_merge_action { MERGE_DISCARD, /* discard the old event */ MERGE_HANDLE, /* handle the old event */ + MERGE_FLUSH, /* handle the old and new event */ MERGE_KEEP, /* keep the old event for future merging */ MERGE_IGNORE /* ignore the new event, keep the old one */ }; @@ -316,6 +317,22 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) { switch (prev->type) { + case 0: + switch (next->type) + { +#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H + case GenericEvent: + if (next->xcookie.extension != xinput2_opcode) break; + if (next->xcookie.evtype != XI_RawMotion) break; + if (x11drv_thread_data()->warp_serial) break; + /* fall through */ +#endif + case ConfigureNotify: + case MotionNotify: + return MERGE_DISCARD; + } + return MERGE_KEEP; + case ConfigureNotify: switch (next->type) { @@ -325,7 +342,7 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) TRACE( "discarding duplicate ConfigureNotify for window %lx\n", prev->xany.window ); return MERGE_DISCARD; } - break; + return MERGE_HANDLE; case Expose: case PropertyNotify: return MERGE_KEEP; @@ -340,7 +357,7 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) TRACE( "discarding duplicate MotionNotify for window %lx\n", prev->xany.window ); return MERGE_DISCARD; } - break; + return MERGE_HANDLE; #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H case GenericEvent: if (next->xcookie.extension != xinput2_opcode) break; @@ -350,8 +367,6 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) } break; case GenericEvent: - if (prev->xcookie.extension != xinput2_opcode) break; - if (prev->xcookie.evtype != XI_RawMotion) break; switch (next->type) { case GenericEvent: @@ -363,7 +378,7 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) } break; } - return MERGE_HANDLE; + return MERGE_FLUSH; }
@@ -409,7 +424,7 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X XEvent event, prev_event; int count = 0; BOOL queued = FALSE; - enum event_merge_action action = MERGE_DISCARD; + enum event_merge_action action;
prev_event.type = 0; while (XCheckIfEvent( display, &event, filter, (char *)arg )) @@ -446,7 +461,7 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X continue; /* filtered, ignore it */ } get_event_data( &event ); - if (prev_event.type) action = merge_events( &prev_event, &event ); + action = merge_events( &prev_event, &event ); switch( action ) { case MERGE_HANDLE: /* handle prev, keep new */ @@ -456,6 +471,11 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X free_event_data( &prev_event ); prev_event = event; break; + case MERGE_FLUSH: /* handle prev and new */ + queued |= call_event_handler( display, &prev_event ); + free_event_data( &prev_event ); + prev_event.type = 0; + /* fall through */ case MERGE_KEEP: /* handle new, keep prev for future merging */ queued |= call_event_handler( display, &event ); /* fall through */