From c3c08b90b67ba42be06a260718c5b6e5939e0b25 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 12 Apr 2022 21:29:02 +0800 Subject: [PATCH] Fix keyboard event device attribution on GTK+ 2 * src/xfns.c (setup_xi_event_mask): Select for raw keypress events on GTK 2. * src/xterm.c (handle_one_xevent): Set pending keystroke time when a raw event is received. * src/xterm.h (struct x_display_info): New flag `pending_keystroke_time_special_p'. --- src/xfns.c | 9 +++++++++ src/xterm.c | 26 +++++++++++++++++++++++++- src/xterm.h | 8 ++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/xfns.c b/src/xfns.c index 5cf3eb41996..2f90534c484 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -3688,6 +3688,15 @@ setup_xi_event_mask (struct frame *f) XISelectEvents (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &mask, 1); + +#if defined USE_GTK && !defined HAVE_GTK3 + memset (m, 0, l); + XISetMask (m, XI_RawKeyPress); + + XISelectEvents (FRAME_X_DISPLAY (f), + FRAME_DISPLAY_INFO (f)->root_window, + &mask, 1); +#endif unblock_input (); } #endif diff --git a/src/xterm.c b/src/xterm.c index e922ab8fbb2..2999480659b 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -14516,7 +14516,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, pending_keystroke_time = dpyinfo->pending_keystroke_time; if (event->xkey.time >= pending_keystroke_time) - dpyinfo->pending_keystroke_time = 0; + { +#if defined USE_GTK && !defined HAVE_GTK3 + if (!dpyinfo->pending_keystroke_time_special_p) +#endif + dpyinfo->pending_keystroke_time = 0; +#if defined USE_GTK && !defined HAVE_GTK3 + else + dpyinfo->pending_keystroke_time_special_p = false; +#endif + } #endif #ifdef USE_GTK @@ -17781,6 +17790,21 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto XI_OTHER; } +#if defined USE_GTK && !defined HAVE_GTK3 + case XI_RawKeyPress: + { + XIRawEvent *raw_event = (XIRawEvent *) xi_event; + + /* This is the only way to attribute core keyboard + events generated on GTK+ 2.x to the extension device + that generated them. */ + dpyinfo->pending_keystroke_time = raw_event->time; + dpyinfo->pending_keystroke_source = raw_event->sourceid; + dpyinfo->pending_keystroke_time_special_p = true; + goto XI_OTHER; + } +#endif + case XI_KeyRelease: #if defined HAVE_X_I18N || defined USE_GTK { diff --git a/src/xterm.h b/src/xterm.h index 85b773cf0bb..69313166db9 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -618,6 +618,14 @@ struct x_display_info Time pending_keystroke_time; int pending_keystroke_source; + +#if defined USE_GTK && !defined HAVE_GTK3 + /* This means the two variables above shouldn't be reset the first + time a KeyPress event arrives, since they were set from a raw key + press event that was sent before the first (real, not sent by an + input method) core key event. */ + bool pending_keystroke_time_special_p; +#endif #endif #ifdef HAVE_XKB -- 2.39.5