[PATCH v2 1/2] winex11: Prevent the call sequence change between xim preedit callback and key event handlers.
Byeongsik Jeon
bsjeon at hanmail.net
Thu Apr 7 16:59:19 CDT 2022
Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
---
v2: rework. update merge_events().
"xim preedit callback" is called from within the XFilterEvent().
Because of the [2/2]'s action, the strings on the 'ERASED' line are
erased.
### xim server sended event sequence ###
preedit start::
preedit draw:: caret 1 chg_first 0 chg_length 0 string 'ㄱ'
preedit draw:: caret 1 chg_first 0 chg_length 1 string '가'
preedit draw:: caret 1 chg_first 0 chg_length 1 string '간'
preedit draw:: caret 0 chg_first 0 chg_length 1 NULL
preedit done::
lookup chars:: keycode 0 string 3 '가' <== HERE
preedit start::
preedit draw:: caret 1 chg_first 0 chg_length 0 string '나'
### Wine process_events() simulated event sequence ###
preedit start::
preedit draw:: caret 1 chg_first 0 chg_length 0 string 'ㄱ'
preedit draw:: caret 1 chg_first 0 chg_length 1 string '가'
preedit draw:: caret 1 chg_first 0 chg_length 1 string '간'
preedit draw:: caret 0 chg_first 0 chg_length 1 NULL
preedit done::
preedit start::
preedit draw:: caret 1 chg_first 0 chg_length 0 string '나' <== ERASED
lookup chars:: keycode 0 string 3 '가' <== HERE
dlls/winex11.drv/event.c | 60 ++++++++++++++++++++++++++--------------
1 file changed, 40 insertions(+), 20 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index c20ceeacca1..581e28787a0 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -261,10 +261,11 @@ static Bool filter_event( Display *display, XEvent *event, char *arg )
enum event_merge_action
{
- MERGE_DISCARD, /* discard the old event */
- MERGE_HANDLE, /* handle the old event */
+ MERGE_FLUSH, /* handle all the events */
MERGE_KEEP, /* keep the old event for future merging */
- MERGE_IGNORE /* ignore the new event, keep the old one */
+ MERGE_IGNORE, /* ignore the new event, keep the old one */
+ MERGE_DISCARD, /* discard the old event */
+ MERGE_HANDLE /* handle the old event */
};
/***********************************************************************
@@ -316,6 +317,19 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
{
switch (prev->type)
{
+ case 0:
+ switch (next->type)
+ {
+ case ConfigureNotify:
+ case MotionNotify:
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+ case GenericEvent:
+#endif
+ return MERGE_DISCARD;
+ default:
+ return MERGE_KEEP;
+ }
+ break;
case ConfigureNotify:
switch (next->type)
{
@@ -325,7 +339,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,30 +354,30 @@ 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;
- if (next->xcookie.evtype != XI_RawMotion) break;
- if (x11drv_thread_data()->warp_serial) break;
+ if (next->xcookie.extension != xinput2_opcode) return MERGE_HANDLE;
+ if (next->xcookie.evtype != XI_RawMotion) return MERGE_HANDLE;
+ if (x11drv_thread_data()->warp_serial) return MERGE_HANDLE;
return MERGE_KEEP;
}
break;
case GenericEvent:
- if (prev->xcookie.extension != xinput2_opcode) break;
- if (prev->xcookie.evtype != XI_RawMotion) break;
+ if (prev->xcookie.extension != xinput2_opcode) return MERGE_HANDLE;
+ if (prev->xcookie.evtype != XI_RawMotion) return MERGE_HANDLE;
switch (next->type)
{
case GenericEvent:
- if (next->xcookie.extension != xinput2_opcode) break;
- if (next->xcookie.evtype != XI_RawMotion) break;
- if (x11drv_thread_data()->warp_serial) break;
+ if (next->xcookie.extension != xinput2_opcode) return MERGE_HANDLE;
+ if (next->xcookie.evtype != XI_RawMotion) return MERGE_HANDLE;
+ if (x11drv_thread_data()->warp_serial) return MERGE_HANDLE;
return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data );
#endif
}
break;
}
- return MERGE_HANDLE;
+ return MERGE_FLUSH;
}
@@ -445,23 +459,29 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X
else
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 */
+ case MERGE_FLUSH: /* handle all the events */
queued |= call_event_handler( display, &prev_event );
- /* fall through */
- case MERGE_DISCARD: /* discard prev, keep new */
free_event_data( &prev_event );
- prev_event = event;
- break;
+ prev_event.type = 0;
+ /* fall through */
case MERGE_KEEP: /* handle new, keep prev for future merging */
queued |= call_event_handler( display, &event );
/* fall through */
case MERGE_IGNORE: /* ignore new, keep prev for future merging */
free_event_data( &event );
break;
+ case MERGE_HANDLE: /* handle prev, keep new */
+ queued |= call_event_handler( display, &prev_event );
+ /* fall through */
+ case MERGE_DISCARD: /* discard prev, keep new */
+ free_event_data( &prev_event );
+ prev_event = event;
+ break;
}
}
if (prev_event.type) queued |= call_event_handler( display, &prev_event );
--
2.35.1
More information about the wine-devel
mailing list