From 15910e5da34a084fe01e0fd96ecf394cb1030e25 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 20 Feb 2022 10:03:28 +0800 Subject: [PATCH] Ignore modifier keys early when handling X key press events * src/xterm.c (handle_one_xevent): Ignore modifier keys earlier without going through the usual key lookup. (x_delete_terminal): Free recorded modifier map. (x_find_modifier_meanings): Record modifier map. * src/xterm.h (struct x_display_info): New field `modmap'. --- src/xterm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/xterm.h | 3 +++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/xterm.c b/src/xterm.c index 64bee110227..4c1c4312172 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -6162,7 +6162,10 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo) dpyinfo->hyper_mod_mask &= ~dpyinfo->super_mod_mask; XFree (syms); - XFreeModifiermap (mods); + + if (dpyinfo->modmap) + XFreeModifiermap (dpyinfo->modmap); + dpyinfo->modmap = mods; } /* Convert between the modifier bits X uses and the modifier bits @@ -9893,6 +9896,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, /* `xkey' will be modified, but it's not important to modify `event' itself. */ XKeyEvent xkey = event->xkey; + int i; #ifdef USE_GTK /* Don't pass keys to GTK. A Tab will shift focus to the @@ -9924,6 +9928,27 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (modifiers & dpyinfo->meta_mod_mask) memset (&compose_status, 0, sizeof (compose_status)); +#ifdef HAVE_XKB + if (FRAME_DISPLAY_INFO (f)->xkb_desc) + { + XkbDescRec *rec = FRAME_DISPLAY_INFO (f)->xkb_desc; + + if (rec->map->modmap && rec->map->modmap[xkey.keycode]) + goto done_keysym; + } + else +#endif + { + if (dpyinfo->modmap) + { + for (i = 0; i < 8 * dpyinfo->modmap->max_keypermod; i++) + { + if (xkey.keycode == dpyinfo->modmap->modifiermap[i]) + goto done_keysym; + } + } + } + #ifdef HAVE_X_I18N if (FRAME_XIC (f)) { @@ -11545,6 +11570,27 @@ handle_one_xevent (struct x_display_info *dpyinfo, } #endif +#ifdef HAVE_XKB + if (FRAME_DISPLAY_INFO (f)->xkb_desc) + { + XkbDescRec *rec = FRAME_DISPLAY_INFO (f)->xkb_desc; + + if (rec->map->modmap && rec->map->modmap[xev->detail]) + goto done_keysym; + } + else +#endif + { + if (dpyinfo->modmap) + { + for (i = 0; i < 8 * dpyinfo->modmap->max_keypermod; i++) + { + if (xkey.keycode == dpyinfo->modmap->modifiermap[xev->detail]) + goto done_keysym; + } + } + } + #ifdef HAVE_XKB if (dpyinfo->xkb_desc) { @@ -16743,6 +16789,9 @@ x_delete_terminal (struct terminal *terminal) XCloseDisplay (dpyinfo->display); #endif #endif /* ! USE_GTK */ + + if (dpyinfo->modmap) + XFreeModifiermap (dpyinfo->modmap); /* Do not close the connection here because it's already closed by X(t)CloseDisplay (Bug#18403). */ dpyinfo->display = NULL; diff --git a/src/xterm.h b/src/xterm.h index f58fa0fe54d..14457b32cc2 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -526,6 +526,9 @@ struct x_display_info Atom Xatom_Meta, Xatom_Super, Xatom_Hyper, Xatom_ShiftLock, Xatom_Alt; #endif + /* Core modifier map when XKB is not present. */ + XModifierKeymap *modmap; + #ifdef HAVE_XRANDR int xrandr_major_version; int xrandr_minor_version; -- 2.39.5