#1990·kitty

Issue with custom XKB keymap

Author: infokillerCreated Sep 22, 2019Updated Nov 30, 2024

Thanks for this terminal - it's really the best I've seen so far!

As for my issue: I'm running a custom XKB keymap which uses CapsLock as another modifier (ISO_LEVEL5_Shift), and I configured CapsLock+Alt+j to redirect to the Home key. Most applications work fine with that setting, including other terminal emulators I tested. However, Kitty seems to pass different keys to the running application, which I tested by using Ctrl-v in a shell.

Here's the Kitty keyboard debug log I'm seeing:

❯ kitty --debug-keyboard --config /dev/null
Press scancode: 0x42 clean_sym: ISO_Level5_Shift composed_sym: ISO_Level5_Shift mods: none glfw_fallback_key: 280 (CAPS LOCK) xkb_key: 65509 (Caps_Lock)
on_key_input: glfw key: 280 native_code: 0xffe5 action: PRESS mods: 0x0 text: '' state: 0 sent key to child
Press scancode: 0x40 clean_sym: Alt_L composed_sym: Alt_L active_unknown_mods: Mod3 mods: none glfw_key: 342 (LEFT ALT) xkb_key: 65513 (Alt_L)
on_key_input: glfw key: 342 native_code: 0xffe9 action: PRESS mods: 0x0 text: '' state: 0 sent key to child
Press scancode: 0x6e clean_sym: Home composed_sym: Home active_unknown_mods: Mod3 mods: alt glfw_key: 268 (HOME) xkb_key: 65360 (Home)
on_key_input: glfw key: 268 native_code: 0xff50 action: PRESS mods: 0x4 text: '' state: 0 sent key to child
Release scancode: 0x6e clean_sym: Home mods: alt glfw_key: 268 (HOME) xkb_key: 65360 (Home)
on_key_input: glfw key: 268 native_code: 0xff50 action: RELEASE mods: 0x4 text: '' state: 0 ignoring as keyboard mode does not allow release events
Release scancode: 0x40 clean_sym: Alt_L mods: alt glfw_key: 342 (LEFT ALT) xkb_key: 65513 (Alt_L)
on_key_input: glfw key: 342 native_code: 0xffe9 action: RELEASE mods: 0x4 text: '' state: 0 ignoring as keyboard mode does not allow release events
Release scancode: 0x42 clean_sym: ISO_Level5_Shift mods: none glfw_fallback_key: 280 (CAPS LOCK) xkb_key: 65509 (Caps_Lock)
on_key_input: glfw key: 280 native_code: 0xffe5 action: RELEASE mods: 0x0 text: '' state: 0 ignoring as keyboard mode does not allow release events

Looking at the log, I suspect the issue is the PRESS mods: 0x4 part, where Kitty treats the alt mod as pressed. Here's a relevant excerpt from my XKB keymap file:

c
    key <AC07> {
        type = "EIGHT_LEVEL_ALPHABETIC",
        symbols[Group1] = [ j, J, j, J],
        actions[Group1] = [ NoAction(),  NoAction(), NoAction(), NoAction(), RedirectKey(key =<LEFT>,clearMods =LevelFive), RedirectKey(key =<LEFT>,clearMods =LevelFive), RedirectKey(key =<HOME>,clearMods =Alt+LevelFive),  RedirectKey(key =<HOME>,clearMods =Alt+LevelFive) ],
    };

Running xev -event keyboard shows that the mod is correctly set by XKB:

❯ xev -event keyboard
Outer window is 0x6400001, inner window is 0x6400002

KeymapNotify event, serial 24, synthetic NO, window 0x0,
    keys:  4294967234 0   0   0   16  0   0   0   0   0   0   0   0   0   0   0
           0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

KeymapNotify event, serial 24, synthetic NO, window 0x0,
    keys:  4294967234 0   0   0   16  0   0   0   0   0   0   0   0   0   0   0
           0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

KeyRelease event, serial 25, synthetic NO, window 0x6400001,
    root 0x1e4, subw 0x0, time 552656814, (508,983), root:(1364,1015),
    state 0x0, keycode 36 (keysym 0xff0d, Return), same_screen YES,
"   XLookupString gives 1 bytes: (0d) "
    XFilterEvent returns: False

KeyPress event, serial 28, synthetic NO, window 0x6400001,
    root 0x1e4, subw 0x0, time 552661215, (508,983), root:(1364,1015),
    state 0x0, keycode 66 (keysym 0xfe11, ISO_Level5_Shift), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyPress event, serial 28, synthetic NO, window 0x6400001,
    root 0x1e4, subw 0x0, time 552661215, (508,983), root:(1364,1015),
    state 0x20, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyPress event, serial 28, synthetic NO, window 0x6400001,
    root 0x1e4, subw 0x0, time 552661607, (508,983), root:(1364,1015),
    state 0x0, keycode 110 (keysym 0xff50, Home), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 28, synthetic NO, window 0x6400001,
    root 0x1e4, subw 0x0, time 552661678, (508,983), root:(1364,1015),
    state 0x0, keycode 110 (keysym 0xff50, Home), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 28, synthetic NO, window 0x6400001,
    root 0x1e4, subw 0x0, time 552662102, (508,983), root:(1364,1015),
    state 0x28, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 28, synthetic NO, window 0x6400001,
    root 0x1e4, subw 0x0, time 552662103, (508,983), root:(1364,1015),
    state 0x20, keycode 66 (keysym 0xfe11, ISO_Level5_Shift), same_screen YES,
    XLookupString gives 0 bytes:

Specifically, see this part from that log:


KeyPress event, serial 28, synthetic NO, window 0x6400001,
    root 0x1e4, subw 0x0, time 552661607, (508,983), root:(1364,1015),
    state 0x0, keycode 110 (keysym 0xff50, Home), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

As you can see in the bolded part, the state of the modifiers is set to 0x0, which means no modifiers should be active.