kovidgoyal / kitty

Cross-platform, fast, feature-rich, GPU based terminal
https://sw.kovidgoyal.net/kitty/
GNU General Public License v3.0
24.25k stars 976 forks source link

[regression] control key not working anymore (xmodmap related?) #3514

Closed CastixGitHub closed 3 years ago

CastixGitHub commented 3 years ago

Describe the bug I upgraded kitty version to v0.20.1 and I noticed that when I press Ctrl-c kitty prints 9;13u I saw the issue https://github.com/kovidgoyal/kitty/issues/3471 So I did checkout to c989a71 (marked as latest working for issue #3471 ) but it wasn't working either So i did checkout to v0.19.3 and It was working Checkout to v0.20.0 again brings the issue

To Reproduce Hit Control and d on the keyboard kitty should exit, instead it prints something

Debug

$ kitty --debug-keyboard  # here I pressed C-c but with Super mapped to Control with xmodmap
Loading new XKB keymaps
Modifier indices alt: 0x3 super: 0x2 hyper: 0x6 meta: 0xffffffff numlock: 0x4 shift: 0x0 capslock: 0x1
Press xkb_keycode: 0x85 clean_sym: Super_L composed_sym: Super_L mods: none glfw_key: 57444 (LEFT_SUPER) xkb_key: 65515 (Super_L)
on_key_input: glfw key: 57444 native_code: 0xffeb action: PRESS mods: 0x0 text: '' state: 0 ignoring as keyboard mode does not allow repeat events
Press xkb_keycode: 0x36 clean_sym: c composed_sym: c mods: ctrl+super glfw_key: 99 (c) xkb_key: 99 (c)
on_key_input: glfw key: 99 native_code: 0x63 action: PRESS mods: 0xc text: '' state: 0 sent key to child
Release xkb_keycode: 0x36 clean_sym: c mods: ctrl+super glfw_key: 99 (c) xkb_key: 99 (c)
on_key_input: glfw key: 99 native_code: 0x63 action: RELEASE mods: 0xc text: '' state: 0 ignoring as keyboard mode does not allow release events
Release xkb_keycode: 0x85 clean_sym: Super_L mods: ctrl+super glfw_key: 57444 (LEFT_SUPER) xkb_key: 65515 (Super_L)
on_key_input: glfw key: 57444 native_code: 0xffeb action: RELEASE mods: 0xc text: '' state: 0 ignoring as keyboard mode does not allow release events

Environment details OS: Arch

# # using caps lock as i3wm mod4 and super as control and adding also some extra delete
# # I didn't change this file recently
$ cat ~/.Xmodmap 
clear Lock
clear mod4
keycode 66 = Hyper_L
add mod4 = Hyper_L

keycode 107 = Control_R
add control = Super_L

keycode 179 = BackSpace
keycode 245 = Delete
keycode 164 = Delete
keycode 235 = Control_L 

Additional context see #3471

amend Actually I don't think it's xmodmap related, because it doesn't work either with the bare control key example with control-c (not super-c)

kitty --debug-keyboard --config NONE
Loading new XKB keymaps
Modifier indices alt: 0x3 super: 0x2 hyper: 0x6 meta: 0xffffffff numlock: 0x4 shift: 0x0 capslock: 0x1
Press xkb_keycode: 0x25 clean_sym: Control_L composed_sym: Control_L mods: none glfw_key: 57442 (LEFT_CONTROL) xkb_key: 65507 (Control_L)
on_key_input: glfw key: 57442 native_code: 0xffe3 action: PRESS mods: 0x0 text: '' state: 0 ignoring as keyboard mode does not allow repeat events
Press xkb_keycode: 0x36 clean_sym: c composed_sym: c mods: ctrl+super glfw_key: 99 (c) xkb_key: 99 (c)
on_key_input: glfw key: 99 native_code: 0x63 action: PRESS mods: 0xc text: '' state: 0 sent key to child
Release xkb_keycode: 0x36 clean_sym: c mods: ctrl+super glfw_key: 99 (c) xkb_key: 99 (c)
on_key_input: glfw key: 99 native_code: 0x63 action: RELEASE mods: 0xc text: '' state: 0 ignoring as keyboard mode does not allow release events
Release xkb_keycode: 0x25 clean_sym: Control_L mods: ctrl+super glfw_key: 57442 (LEFT_CONTROL) xkb_key: 65507 (Control_L)
on_key_input: glfw key: 57442 native_code: 0xffe3 action: RELEASE mods: 0xc text: '' state: 0 ignoring as keyboard mode does not allow release events

Thank you

kovidgoyal commented 3 years ago

It's definitely xmodmap related. Remove it and restart X and you will be fine. As for fixing, it this is likely to be the same issue as #3446 pinging @orki

orki commented 3 years ago

@CastixGitHub Could you run xkbcomp $DISPLAY debug.txt and attach the resulting file called debug.txt?

orki commented 3 years ago

My best guess, without the xkb dump, is that control and super are mapped to the same modifier index. If that is correct, the attached patch should "fix" it by giving control precedence over super:

diff --git a/glfw/xkb_glfw.c b/glfw/xkb_glfw.c
index c46f91b9..a1feab0d 100644
--- a/glfw/xkb_glfw.c
+++ b/glfw/xkb_glfw.c
@@ -324,8 +324,14 @@ glfw_xkb_update_masks(_GLFWXKBData *xkb) {
     unsigned used_bits = 0; /* To avoid using the same bit twice */
     XkbDescPtr xkb_ptr = XkbGetMap( _glfw.x11.display, XkbVirtualModsMask | XkbVirtualModMapMask, XkbUseCoreKbd );

+    /* shift, control, and capsLock are special; they cannot be identified reliably on X11 */
+#define S(a, n) xkb->a##Idx = xkb_keymap_mod_get_index(xkb->keymap, n); xkb->a##Mask = 1 << xkb->a##Idx; used_bits |= xkb->a##Mask;
+    S(control, XKB_MOD_NAME_CTRL);
+    S(shift, XKB_MOD_NAME_SHIFT);
+    S(capsLock, XKB_MOD_NAME_CAPS);
+#undef S
 #define S( a ) xkb->a##Idx = XKB_MOD_INVALID; xkb->a##Mask = 0
-    S(control); S(alt); S(shift); S(super); S(hyper); S(meta); S(capsLock); S(numLock);
+    S(alt); S(super); S(hyper); S(meta); S(numLock);
 #undef S
     if (xkb_ptr) {
         Status status = XkbGetNames(_glfw.x11.display, XkbVirtualModNamesMask, xkb_ptr);
@@ -361,9 +367,6 @@ glfw_xkb_update_masks(_GLFWXKBData *xkb) {
         }
     }
 #define S(a, n) xkb->a##Idx = xkb_keymap_mod_get_index(xkb->keymap, n); xkb->a##Mask = 1 << xkb->a##Idx;
-    S(control, XKB_MOD_NAME_CTRL);
-    S(shift, XKB_MOD_NAME_SHIFT);
-    S(capsLock, XKB_MOD_NAME_CAPS);
     if (!succeeded) {
         S(numLock, XKB_MOD_NAME_NUM);
         S(alt, XKB_MOD_NAME_ALT);

@CastixGitHub Could you let me know whether this fixes your problem?

CastixGitHub commented 3 years ago

Thank you, the patch works! Here's the debug log anyway, for completeness debug.txt