I have two keyboard layouts, English and Russian. I noticed that when the active layout is Russian and I press Ctrl+C, sakura and xterm cancel the currently running command, but kitty does not. Same for Ctrl+D, sakura and xterm exit terminal, but kitty does not.
This is because kitty recognized the cyrillic letters being pressed and ignores such weird commands.
# Ctrl+C in English layout
scancode: 0x25 release: 0 clean_sym: Control_L composed_sym: Control_L mods: numlock glfw_key: LEFT CONTROL
scancode: 0x36 release: 0 clean_sym: c composed_sym: c mods: ctrl+numlock glfw_key: C
scancode: 0x36 release: 1 clean_sym: c mods: ctrl+numlock glfw_key: C
scancode: 0x25 release: 1 clean_sym: Control_L mods: ctrl+numlock glfw_key: LEFT CONTROL
# Ctrl+C in Russian layout
scancode: 0x25 release: 0 clean_sym: Control_L composed_sym: Control_L mods: numlock glfw_key: LEFT CONTROL
scancode: 0x36 release: 0 clean_sym: Cyrillic_es composed_sym: Cyrillic_es mods: ctrl+numlock glfw_key: UNKNOWN
scancode: 0x36 release: 1 clean_sym: Cyrillic_es mods: ctrl+numlock glfw_key: UNKNOWN
scancode: 0x25 release: 1 clean_sym: Control_L mods: ctrl+numlock glfw_key: LEFT CONTROL
It would be much much more pleasant if kitty would be layout agnostic and bind itself to the scancodes instead of ascii letters. In fact, my i3 has all shortcuts configured by scancodes so that the desired action consistently happens regardless of the currently active keyboard layout.
Ctrl+Shift+C is another common annoyance, when Russian layout is active, kitty doesn't copy the selection.
I'm thinking now, ideally kitty would ignore active layout and think that I have english layout when Ctrl is pressed, so that for example even Ctrl+/ is treated exactly as Ctrl+/ regardless of active layout (in Russian keyboard that physical key represents .). This doesn't happen today in sakura or xterm.
And doing that would make it impossible to use compose keys to enter non-english text. Which would make lots of other people unhappy, see #171
I read the thread, but didn't fully understand why it would prevent using compose keys, could you explain a bit more?
I have something like that working on my laptop, I press AltGr+o, / to make a Danish letter ø, is that what compose key is and why this would break?
Because compose keys in general work by using some modifier to change the action of normal keys or by re-assigning normal keys to mean something else. There is no way for a key event consuming application to know which is which. Either an application uses the compose and layout rules to figure out which key the user meant to press, or it does not. It cannot do so selectively on an ad hoc basis.
Your russian keyboard layout is mapping the c key to some cyrillic character. if you dont like that, the proper solution is to modify the russian layout, not add workarounds or it to every application you use.
The layout maps all keys to cyrillic characters as Russian uses cyrillic alphabet instead of Latin one, that's the whole point of having the second layout in the first place 😀
Problem is, currently kitty terminal cannot be controlled if you only have Russian layout, you have to install English layout just to get the Latin letter "C" so that kitty can start recognizing Ctrl+C and Ctrl+Shift+C. Other terminals manage to understand these key presses regardless of active layout (and by the way, I am able to type AltGr+o, / to get Danish ø in sakura terminal).
Regardless, this pain extends beyond kitty, I didn't have high hopes for this issue to be solved. Thanks for explanations though 😉
In that case what you need to do is add rules to the layout to map Ctrl+C to Ctrl+C and not ctrl+<cyrillic character>. Indeed, while it has been a long time since I looked at xkb layouts, I am fairly sure you can easily create rules to map Ctrl+<any key> to ctrl+<any key>
That should fix it in all applications that respect keyboard layouts.
Interesting, I will have a look, thanks for the idea!
This was a very neat idea, but unfortunately I couldn't find how to do this. There is a keymap table where you can define what a given key should do depending on the currently hold modifier keys, but Ctrl is not in that list. All I saw about Ctrl is people reassigning it to a different key, but that doesn't help us here.
If someone finds a solution, please share.
Did you look at XCompose?
Not yet, just started looking 👍
But look what I found in meantime with xev, this is curious!
English layout, press "d", xev sees it as "d" (expected):
KeyPress event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 287760, (-807,-100), root:(1140,0),
state 0x10, keycode 40 (keysym 0x64, d), same_screen YES,
XLookupString gives 1 bytes: (64) "d"
XmbLookupString gives 1 bytes: (64) "d"
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 287884, (-807,-100), root:(1140,0),
state 0x10, keycode 40 (keysym 0x64, d), same_screen YES,
XLookupString gives 1 bytes: (64) "d"
XFilterEvent returns: False
Russian layout, press "d", xev sees it as cyrillic "в" (expected):
KeyPress event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 507942, (-490,157), root:(1457,257),
state 0x2010, keycode 40 (keysym 0x6d7, Cyrillic_ve), same_screen YES,
XLookupString gives 2 bytes: (d0 b2) "в"
XmbLookupString gives 2 bytes: (d0 b2) "в"
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 508090, (-490,157), root:(1457,257),
state 0x2010, keycode 40 (keysym 0x6d7, Cyrillic_ve), same_screen YES,
XLookupString gives 2 bytes: (d0 b2) "в"
XFilterEvent returns: False
English layout, press "Ctrl+d", xev sees it as "Ctrl+d" (expected):
KeyPress event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 309258, (-1349,-37), root:(598,63),
state 0x10, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 310271, (-1349,-37), root:(598,63),
state 0x14, keycode 40 (keysym 0x64, d), same_screen YES,
XLookupString gives 1 bytes: (04) ""
XmbLookupString gives 1 bytes: (04) ""
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 310441, (-1349,-37), root:(598,63),
state 0x14, keycode 40 (keysym 0x64, d), same_screen YES,
XLookupString gives 1 bytes: (04) ""
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 310973, (-1349,-37), root:(598,63),
state 0x14, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
Russian layout, press "Ctrl+d", xev sees it as latin "Ctrl+d":
KeyPress event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 538564, (-342,490), root:(1605,590),
state 0x2010, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 540366, (-342,490), root:(1605,590),
state 0x2014, keycode 40 (keysym 0x64, d), same_screen YES,
XLookupString gives 1 bytes: (04) ""
XmbLookupString gives 1 bytes: (04) ""
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 540546, (-342,490), root:(1605,590),
state 0x2014, keycode 40 (keysym 0x64, d), same_screen YES,
XLookupString gives 1 bytes: (04) ""
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0x2c00001,
root 0x1cf, subw 0x0, time 540946, (-342,490), root:(1605,590),
state 0x2014, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
I'm tempted to say kitty should do the same since xev does this out of the box, what do you think?
Take it up with the maintainers of libxkbcommon. It isn't kitty that decides what keys to report, it is libxkbcommon. See the glfw_xkb_handle_key_event function. IIRC xev doesn't use libxkbcommon it uses xlib. Most modern software uses libxkbcommon since it works with both X and wayland.
Another application-level idea: can we make kitty accept bindings for cyrillic letters? For example:
map ctrl+shift+м paste_from_clipboard
Or if it has to be a keysym reported by GLFW_DEBUG_KEYBOARD=1 kitty, then:
map ctrl+shift+cyrillic_em paste_from_clipboard
At the minimum, I'd like to be able to add 4 bindings so that these work when Russian is the active layout: Ctrl+C, Ctrl+D, Ctrl+Shift+C, Ctrl+Shift+V.
It has to be keys known to glfw, since the kitty layer sees only glfw key codes. And glfw does not have codes for keys beyond the basic ascii keys. But, thinking about it, one way to do this is that, if the key is unknown to glfw in the current layout, then use the key name from a fallback keyboard layout that can be configured via a config option in kitty.
That should be robust against changes in kernel/graphics stack and that way the user can configure exactly what layout to use a fallback for keys that do not match. The only question is, how to get xkb to load such a layout. Currently it loads the layout from the X server or wayland compsitor. I think this API is what we need https://xkbcommon.org/doc/current/group__keymap.html#ga502717aa7148fd17d4970896f1e9e06f
And, I dont think this even needs a kitty config option, since it is controlled via an environment variable already, see https://xkbcommon.org/doc/current/structxkb__rule__names.html
Note that I have not tested the fix, I leave that to you.
Wooohooo, it works, thank you so much!!! 🎉 No more annoyances when I copy something with Ctrl+Shift+C only to realize later that I didn't copy anything because my layout was Russian.
Ctrl+C, Ctrl+D, Ctrl+Shift+C, Ctrl+Shift+V, all work now in Russian layout — and by the way I didn't have to configure absolutely anything, not even environment variables, I think it figures out the fallback on its own because I have both layouts configured.
This issue should probably be reopened now, since the fix implemented in 4711746f8f0e7afc8236c2a6eb59851cace3f592 no longer works: Cyrillic characters were added to xkb_glfw.c in e619eb9cbb5a7690afab09da688ac4c432b9c252 and thus are not unknown to GLFW anymore.
Maybe I don't understand the full picture here, but I cannot imagine a use case for a keybinding attached to a Cyrillic letter — a user would have to switch layouts to access that keybinding, making it rather impractical. On the other hand, the effect of the change in e619eb9cbb5a7690afab09da688ac4c432b9c252 is that now I have to manually add mappings to kitty.conf for each Cyrillic letter and each combination of modifiers in order to have layout-independent keybindings — and I do want <Ctrl-C> and <Ctrl-D> and <Ctrl-Z>, and the line-editing stuff, and the Kitty copy-paste shortcuts, etc. to work independently on what layout I'm currently in.
(Strictly speaking, 4711746f8f0e7afc8236c2a6eb59851cace3f592 does not provide fully layout-agnostic keybindings for Cyrillic layouts, since some punctuation characters, "known" to GLFW, are moved to different positions. But it is probably as good as a keysym-based solution can be.)
I dont really see what can be done here. shortcuts needed to be mapped to letters after the keyboard layout is done. Otherwise you cannot use for example a dvorak layout, or any layout that remaps keys. If pressing ctrl+c on your keyboard generates keycodes for ctrl+(something else) after layout mapping, then you have to bind to that (something else) in kitty.conf.
The only real solution would be to have an smap command that maps to values in the default/no layout case. In order to do that, the entire keyboard handling stack in glfw (both xkb and cocoa) and kitty would need to be re-written to pass two keycodes to kitty, the code after layout mapping and the code before layout mapping. And there was an effort underway to do that by @bew see #2000
I suggest you contribute to that effort if you want to move this forward.
According to https://sw.kovidgoyal.net/kitty/conf.html#keyboard-shortcuts, one should be able to use raw system key codes but when I tested it, I couldn't get it to work.
raw system codes only apply if the key is unknown to glfw which cyrillic
keys no longer are.
Ok. I think that should be mentioned in the docs.
@Luflosi Independently of the big effort in #2000, I am not sure what is the benefit of having Cyrillic characters in xkb_glfw.c in e619eb9cbb5a7690afab09da688ac4c432b9c252. Why should they be known to GLFW?
The discussion in the PR, #1928, seems to suggest that this was not accepted by the upstream GLFW project, and is a Kitty innovation, so I share @tertium's skepticism. However, I haven't read the entire thread in #1928, so there might be good reasons for it.
@tertium It all started when I wanted to be able to bind any key on my German keyboard in kitty. On German keyboards, there are additional characters not found on the English layout like äöüß and basically all of the non-alphanumeric characters are in different places. Since many other non-English keyboard layouts were also not fully supported, I just added them too while I was at it. The addition of Cyrillic characters might be debatable in terms of its usefulness but I saw no reason not to add them. Feel free to remove them again in your fork if they bother you. I am even willing to provide you with a patch if you find it too difficult to do yourself. But the correct way to achieve what you want is not to remove the keys from GLFW but to do what is described in #2000.
@ctrlcctrlv Yes, keyboard handling is very different in kitty's version of GLFW compared to the original GLFW because the original keyboard handling was insufficient for kitty, see for example https://github.com/glfw/glfw/issues/1140.
To make myself clear, I do see the point of adding the characters like ä or é which are part of the primary layout in national keyboards. So a user of a German or Swedish keyboard may indeed want to assign a keybinding to Ctrl-ä, and for that, GLFW must know the symbol.
However, I don't think it makes sense for alternate alphabets like Cyrillic, since these are usually delegated to a separate ISO group: pretty much every Russian-speaking user would have us,ru as their XKB layout. In this case, I think it is better to keep the cyrillic characters unknown, so that the fix for #606 could work.
Edit: @Luflosi I posted my comment before seeing yours. Removing the cyrillic symbols from xkb_glfw.c is exactly what I did, so right now I am a happy camper :) Thank you for offering a patch.
In https://github.com/kovidgoyal/kitty/issues/606#issuecomment-396070331, @maximbaz asked for keyboard bindings with Cryllic letters, so there seems to be at least some use case for supporting them.
In #606 (comment), @maximbaz asked for keyboard bindings with Cryllic letters, so there seems to be at least some use case for supporting them.
Well, he asked for this because the standard shortcuts (Ctrl-C, Ctrl-D, copy-paste) didn't work for him out of the box, and so he looked for a workaround. But it is a very inconvenient workaround, since you would have to add _a lot_ of such bindings to make everything work. Instead, 4711746f8f0e7afc8236c2a6eb59851cace3f592 fixed his original problem without requiring him to do anything at all — until e619eb9cbb5a7690afab09da688ac4c432b9c252, which invalidated the fix.
(Not trying to start an argument, nor waste your time. My problem is solved, so now I just want to explain my reasoning. I do understand your position, too.)
Personally, I have no opinion on the appropriateness of adding cyrillic
keys or not. I am interested in solving this and all the keyboard issues
properly by having GLFW pass all relevant information to kitty so it can
decide for itself. That will mean layout-ed key in the current layout
and in the default layout. Clean key shifted key, etc etc.
In the meantime I suggest simply adding the mappings for the shortcuts
you need to kitty.conf or patching out the cyrillic keys.
Rather surprising to see an advanced terminal emulator (graphics protocol, hinting, remote control, etc) has issues with such a basic thing as keyboard layouts :) Ok, I can add additional shortcuts to kitty.conf with Russian letters for kitty-specific actions. Do I understand it right that there is currently no way to deal with shell keybindings (like Ctrl-C, Ctrl-D, Ctrl-Z) in kitty with Russian layout? (without digging into the code, to be sure).
No, you understand wrong. See send_text.
Works, thanks.
Most helpful comment
Personally, I have no opinion on the appropriateness of adding cyrillic
keys or not. I am interested in solving this and all the keyboard issues
properly by having GLFW pass all relevant information to kitty so it can
decide for itself. That will mean layout-ed key in the current layout
and in the default layout. Clean key shifted key, etc etc.
In the meantime I suggest simply adding the mappings for the shortcuts
you need to kitty.conf or patching out the cyrillic keys.