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

From: Pip Cet <[email-masked]>
Date: Sat, 30 Nov 2024 16:37:03 +0000

On Saturday, November 30th, 2024 at 10:55, Gerd Möllmann <[email-masked]> wrote:
> Helmut Eller [email-masked] writes:
> 
> > On Fri, Nov 29 2024, Gerd Möllmann wrote:
> > 
> > > > Not sure if that is used in your build, but in x_display_info (xterm.h)
> > > > I see a number of struct frame pointers that are not fixed in fix_frame,
> > > > starting with
> > > > 
> > > > struct frame *x_focus_frame;
> > > > 
> > > > And if it's not that display info that is being used, I'd bet a small
> > > > amount that whatever is actually used (pgtk_display_info?) has a similar
> > > > problems.
> > > > 
> > > > (Can't fix this myself, sorry, I only have macOS.)
> > 
> > I think the x_display_info struct (I guess usually only one exists) is
> > allocated in x_term_init (or pgtk_term_init) with igc_xzalloc_ambig. So
> > theoretically it doesn't need to be traced.
> 
> 
> Then we're good, sorry for the noise.

So it turns out X input method handling is somewhat complicated!

I've tried installing fcitx, but it seems to be working the same here with and without MPS.

It would help to establish the value of x-gtk-use-native-input, since that determines whether we use the GTK or X method for communicating with fcitx.

I've attached a patch which logs some debugging info to stderr (because displaying messages using X while debugging X code is a bad idea, IME). If you could apply it and reproduce the output around a keypress that's handled incorrectly, that might help us track this down.

Pip

diff --git a/src/xterm.c b/src/xterm.c
index ebcd3a786e2..066d3828bcf 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -6914,6 +6914,7 @@ x_display_info_for_display (Display *dpy)
     if (dpyinfo->display == dpy)
       return dpyinfo;
 
+  fprintf(stderr, "couldn't find display info for %p\n", dpy);
   return 0;
 }
 
@@ -13027,6 +13028,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
       event_display
 	= x_display_info_for_display (next_event.xany.display);
 
+      fprintf(stderr, "event_display %p\n", event_display);
       if (event_display)
 	{
 #ifdef HAVE_X_I18N
@@ -17913,7 +17915,11 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
       && !dpyinfo->prefer_native_input)
     {
 #endif
-      return XFilterEvent (event, f1 ? FRAME_X_WINDOW (f1) : None);
+      bool result;
+      result = XFilterEvent (event, f1 ? FRAME_X_WINDOW (f1) : None);
+      fprintf(stderr, "result %d (not GTK) for event %d, frame %p dpyinfo %p\n", result, event->type,
+	      f1, dpyinfo);
+      return result;
 #ifdef USE_GTK
     }
   else if (f1 && (event->type == KeyPress
@@ -17941,9 +17947,13 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
 	   exercise the wire to make pselect return.  */
 	XNoOp (FRAME_X_DISPLAY (f1));
 
+      fprintf(stderr, "result %d for event %d, frame %p dpyinfo %p\n", result, event->type,
+	      f1, dpyinfo);
       return result;
     }
 
+  fprintf(stderr, "result 0 (no frame) for event %d, frame %p dpyinfo %p\n", event->type,
+	  f1, dpyinfo);
   return 0;
 #endif
 }
@@ -17965,6 +17975,7 @@ event_handler_gdk (GdkXEvent *gxev, GdkEvent *ev, gpointer data)
 
       dpyinfo = x_display_info_for_display (xev->xany.display);
 
+      fprintf(stderr, "dpyinfo %p\n", dpyinfo);
 #ifdef HAVE_X_I18N
       /* Filter events for the current X input method.
          GTK calls XFilterEvent but not for key press and release,