Subject: Re: bug#74590: 31.0.50 [scratch/igc branch]; key input sometimes skip fcitx input method preedit box

From: Pip Cet <[email-masked]>
Date: Wed, 12 Feb 2025 12:44:47 +0000

"Po Lu" <[email-masked]> writes:

> Pip Cet <[email-masked]> writes:
>
>> But Emacs calls XFilterEvent in conjunction with GDK in a weird way,
>> sometimes out of order (and sometimes twice for the same event? I'm not
>> sure I understand this), and once in a while such reordering will result
>> in the fake time wraparound happening and key presses not being
>> filtered.
>>
>> IOW, Emacs treats XFilterEvent as a pure function, but it has side
>> effects which can cause a second return value, or one generated out of
>> order, to differ when input methods are in use.
>>
>> I assume the reason this happens with feature/igc but not with master is
>> that handle_one_xevent can have significant (not user-noticeable, but
>> enough for the time between keypress and keyrelease, maybe) and
>> unexpected latency when GC is happening, but not with the old GC.
>>
>> I don't have a proper fix, but can you try this patch and see what
>> behavior is like with it?
>>
>>
>> diff --git a/src/xterm.c b/src/xterm.c
>> index 80108190590..59d1d7fdaa6 100644
>> --- a/src/xterm.c
>> +++ b/src/xterm.c
>> @@ -24131,7 +24131,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
>>  		  copy.xkey.window = xev->event;
>>  		  copy.xkey.root = xev->root;
>>  		  copy.xkey.subwindow = xev->child;
>> -		  copy.xkey.time = xev->time;
>> +		  fprintf (stderr, "ignoring time %ld\n", (long) xev->time);
>> +		  copy.xkey.time = CurrentTime;
>>  		  copy.xkey.state = state;
>>  		  xi_convert_button_state (&xev->buttons, &copy.xkey.state);
>>
>> @@ -24189,7 +24190,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
>>  	      xkey.window = xev->event;
>>  	      xkey.root = xev->root;
>>  	      xkey.subwindow = xev->child;
>> -	      xkey.time = xev->time;
>> +	      fprintf (stderr, "ignoring time %ld\n", (long) xev->time);
>> +	      xkey.time = CurrentTime;
>>  	      xkey.state = state;
>>  	      xkey.x = lrint (xev->event_x);
>>  	      xkey.y = lrint (xev->event_y);
>> @@ -24631,7 +24633,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
>>  	      xkey.window = xev->event;
>>  	      xkey.root = xev->root;
>>  	      xkey.subwindow = xev->child;
>> -	      xkey.time = xev->time;
>> +	      fprintf (stderr, "ignoring time %ld\n", (long) xev->time);
>> +	      xkey.time = CurrentTime;
>>  	      xkey.state = xi_convert_event_keyboard_state (xev);
>>  	      xkey.x = lrint (xev->event_x);
>>  	      xkey.y = lrint (xev->event_y);
>>
>> At least over here (with the imperfect setup described above), I haven't
>> been able to reproduce the falsely-unfiltered key issue.
>
> I don't think this is correct

I'm not sure I understand which part you think is incorrect.  Passing
CurrentTime as the time in the fake event we call XFilterEvent on is
certainly a hack, not a proper fix (unless it works and nothing better
can be found), but I said that.

I've since confirmed that introducing a random delay before we call
XFilterEvent makes the bug, if that's what I'm observing, appear on the
master branch as well, so this is a timing issue in the XIM (not GTK IM)
code.

> , but Emacs is not supposed to hand events for which XFilterEvent has
> already been involved over to GDK.  It is for this reason that all key
> press events which are registered by Emacs's input window and filtered
> are withheld from GDK, as it generates GDK events in a separate event
> queue that is polled long after handle_one_xevent returns (and the
> time at which GTK's input method conversion transpires is further away
> still).  But this is only material if GTK's XIM input module is
> enabled, for otherwise only non-key events are filtered by GTK, as
> XFilterEvent is not input extension-aware.

x_gtk_use_native_input is false.

Pip