[PATCH 1/2] winex11: Invoke Key event handlers immediately, keeping pace with the XFilterEvent().

Byeongsik Jeon bsjeon at hanmail.net
Tue Apr 5 00:26:51 CDT 2022


On 4/4/22 10:49 PM, Byeongsik Jeon wrote:
> 1. GCS_COMPSTR: XFilterEvent() True case, XIMPreeditDrawCallCallback() is
>                 invoked by XFilterEvent() internally. immediately processing.
>    GCS_RESULTSTR: XFilterEvent() False case. X11DRV_XIMLookupChars() is
>                 invoked by KeyPress event handler. delayed processing.
>    So, delayed event handler processing causes GCS_COMPSTR, GCS_RESULTSTR
>    pair sequence inverting.
> 
>    In Hangul IME, one key often generates GCS_COMPSTR, GCS_RESULTSTR pairs.
>    The XIM server sends the correct order pair, but the message order
>    inverted through the process_events(). Japanese input system can also
>    produce similar situation.
> 
> 2. Copying event variable does not guarantee complete state preservation.
>    At the time of delayed processing, the global information that the event
>    handler must refer to may be changed.
>    Ex. XFilterEvent(), KeyPress event handler confirmed.
> 

Please ignore '2.'. Personally, while testing other issues, I got a
misinterpretation.

"1." is still valid. We must prevent the change in call sequence between
KeyPress, KeyRelease event handlers and XFilterEvent ().


> Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
> ---
>  dlls/winex11.drv/event.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
> index 170111e9c28..149069b0d29 100644
> --- a/dlls/winex11.drv/event.c
> +++ b/dlls/winex11.drv/event.c
> @@ -445,6 +445,19 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X
>              else
>                  continue;  /* filtered, ignore it */
>          }
> +        if (event.type == KeyPress || event.type == KeyRelease)
> +        {
> +            if (prev_event.type)
> +            {
> +                queued |= call_event_handler( display, &prev_event );
> +                free_event_data( &prev_event );
> +                prev_event.type = 0;
> +                action = MERGE_DISCARD;
> +            }
> +            queued |= call_event_handler( display, &event );
> +            continue;
> +        }
> +
>          get_event_data( &event );
>          if (prev_event.type) action = merge_events( &prev_event, &event );
>          switch( action )




More information about the wine-devel mailing list