GNU bug report logs - #74590
31.0.50 [scratch/igc branch]; key input sometimes skip fcitx input method preedit box

Previous Next

Package: emacs;

Reported by: Yikai Zhao <yikai <at> z1k.dev>

Date: Thu, 28 Nov 2024 13:20:02 UTC

Severity: normal

Found in version 31.0.50

Full log


Message #86 received at 74590 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: Yikai Zhao <yikai <at> z1k.dev>
Cc: Po Lu <luangruo <at> yahoo.com>,
 Gerd Möllmann <gerd.moellmann <at> gmail.com>,
 Helmut Eller <eller.helmut <at> gmail.com>, 74590 <at> debbugs.gnu.org
Subject: Re: bug#74590: 31.0.50 [scratch/igc branch];
 key input sometimes skip fcitx input method preedit box
Date: Mon, 17 Feb 2025 19:02:03 +0000
"Yikai Zhao" <yikai <at> z1k.dev> writes:

> I'm sorry to tell you that the issue still happens with your patch. I
> don't see anything abnormal about the printed timestamps when the
> issue happens (no unordered timestamps found).

Oh no!  It seems I missed some cases, which might explain it, but it's
also possible it's an entirely separate issue.  Did it become less
frequent, at least?

> Now I think maybe what you described is not the same issue that I
> encountered. :(

Maybe.  If you still have the time, can you try this extended patch
instead?

diff --git a/src/xterm.c b/src/xterm.c
index c3137945ac5..52052fcc9c3 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -13040,7 +13040,10 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
 		  != event_display->xi2_opcode))
 	    {
 #endif
-	      if (!x_filter_event (event_display, &next_event))
+	      XEvent event_copy = next_event;
+	      if (event_copy.type == KeyPress || event_copy.type == KeyRelease)
+		event_copy.xkey.time = CurrentTime;
+	      if (!x_filter_event (event_display, &event_copy))
 		handle_one_xevent (event_display,
 				   &next_event, &finish, &hold_quit);
 #ifdef HAVE_XINPUT2
@@ -17892,8 +17895,12 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
    XFilterEvent because that's the one for which the IC
    was created.  */
 
+  //usleep (10000);
   struct frame *f1;
 
+  if (event->type == KeyPress || event->type == KeyRelease)
+    if (event->xkey.time > 1)
+      emacs_abort();
 #if defined HAVE_XINPUT2 && defined USE_GTK
   bool xinput_event = false;
   if (dpyinfo->supports_xi2
@@ -17976,9 +17983,13 @@ event_handler_gdk (GdkXEvent *gxev, GdkEvent *ev, gpointer data)
       /* Filter events for the current X input method.
          GTK calls XFilterEvent but not for key press and release,
          so we do it here.  */
+      XEvent xev_copy;
+      xev_copy = *xev;
+      fprintf (stderr, "ignoring time %ld\n", (long) xev_copy.xkey.time);
+      xev_copy.xkey.time = CurrentTime;
       if ((xev->type == KeyPress || xev->type == KeyRelease)
 	  && dpyinfo
-	  && x_filter_event (dpyinfo, xev))
+	  && x_filter_event (dpyinfo, &xev_copy))
 	{
 	  unblock_input ();
 	  return GDK_FILTER_REMOVE;
@@ -24131,7 +24142,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 +24201,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 +24644,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);
@@ -25765,7 +25779,14 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
 	  /* Input extension key events are filtered inside
 	     handle_one_xevent.  */
 #endif
-	  if (x_filter_event (dpyinfo, &event))
+	  XEvent event_copy = event;
+	  if (event_copy.type == KeyPress || event_copy.type == KeyRelease)
+	    {
+	      fprintf (stderr, "ignoring time %ld\n", (long) event.xkey.time);
+	      event_copy.xkey.time = CurrentTime;
+	    }
+
+	  if (x_filter_event (dpyinfo, &event_copy))
 	    continue;
 #ifdef HAVE_XINPUT2
 	}

> To summarize: for feature/igc at 2025/02/10 with or without the patch,
> the issue happens but at a much lower probability (compared to
> scratch/igc at 2024/11/24)

Did you ever see this message?

	fprintf(stderr,
	        "%s,%d: The application disposed a key event with %ld serial.\n",
	        __FILE__, __LINE__,
	        im->private.proto.fabricated_serial);

It should be printed on stderr when an out-of-order event arrives in
XFilterEvent.

> I think I will try bisecting between the two versions and see what affects this.

That sounds like a lot of work!  Sorry I couldn't come up with anything
but the patch above, and I understand if you don't want to try it, but
if you do, please let me know how it goes!

And if you can find a better recipe for reproducing this, please let us
know, too.

Thanks again for the report.

Pip





This bug report was last modified 109 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.