-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ctrl+w functionality #17
Comments
I cannot reproduce this, with the following vimrc nnoremap <C-w> dw Then pressing Ctrl-W in normal mode in vim deletes the word under the cursor for me. And, in command mode, pressing Ctrl-V then Ctrl-W yields ^W which indicates that kitty is correctly sending ^W to vim. |
tl;dr "Key events relate to actual physical keyboard keys, whereas character events relate to the Unicode code points generated by pressing some of them." Thank you for checking and the fast response. This turned out to be a bit more complex and my setup is in part culprit. I use dvorak keyboard layout and this would also affect AZERTY layouts and other non-qwerty keyboards may be affected in different ways too. After checking the (glfw documentation)[http://www.glfw.org/docs/latest/input_guide.html#input_char] started trying to understand what needed to be checked. I failed a bit and then came to see that the input worked correctly on https://github.com/glfw/glfw/blob/master/tests/events.c (short ref f29c9630) the translated/real key is named "name" on this events.c (line 368 key_callback function). So I changed a couple of files to get this working: 17:33 seb@amon:[/data/git/kitty] (master *$%=)$ git diff kitty/glfw.c
diff --git a/kitty/glfw.c b/kitty/glfw.c
index d77d1c4..4b1bfea 100644
--- a/kitty/glfw.c
+++ b/kitty/glfw.c
@@ -59,7 +59,7 @@ char_mods_callback(GLFWwindow *w, unsigned int codepoint, int mods) {
static void
key_callback(GLFWwindow *w, int key, int scancode, int action, int mods) {
- WINDOW_CALLBACK(key_callback, "iiii", key, scancode, action, mods);
+ WINDOW_CALLBACK(key_callback, "iiiis", key, scancode, action, mods, glfwGetKeyName(key, scancode));
}
17:34 seb@amon:[/data/git/kitty] (master *$%=)$ git diff kitty/keys.py
diff --git a/kitty/keys.py b/kitty/keys.py
index b8cef95..46e505b 100644
--- a/kitty/keys.py
+++ b/kitty/keys.py
@@ -48,29 +48,42 @@ control_codes[defines.GLFW_KEY_DELETE] = bytearray(key_as_bytes('kdch1').replace
alt_codes = {k: (0x1b, k) for i, k in enumerate(range(defines.GLFW_KEY_SPACE, defines.GLFW_KEY_RIGHT_BRACKET + 1))}
-def interpret_key_event(key, scancode, mods):
+def interpret_key_event(key, scancode, mods,name):
17:36 seb@amon:[/data/git/kitty] (master *$%=)$ git diff kitty/boss.py
diff --git a/kitty/boss.py b/kitty/boss.py
index 1450daa..c7d3405 100644
--- a/kitty/boss.py
+++ b/kitty/boss.py
@@ -254,7 +254,7 @@ class Boss(Thread):
w.write_to_child(data)
@callback
- def on_key(self, window, key, scancode, action, mods):
+ def on_key(self, window, key, scancode, action, mods, name):
is_key_pressed[key] = action == GLFW_PRESS
self.start_cursor_blink()
self.cursor_blink_zero_time = monotonic()
@@ -281,7 +281,9 @@ class Boss(Thread):
if window.screen.auto_repeat_enabled or action == GLFW_PRESS:
if window.char_grid.scrolled_by and key not in MODIFIER_KEYS:
window.scroll_end()
- data = interpret_key_event(key, scancode, mods)
+ # name variable comes with effective casing but the control codes
+ # are set towards strictly upppercase letters, so we uppercase them:
+ data = interpret_key_event(ord(name.upper()), scancode, mods, name)
if data:
window.write_to_child(data)
This gets Ctrl + D, Ctrl + W, Ctrl + C working, but, backspace is broken now, I will try to fix that soon and send a PR or something. Thanks, |
I'm somewhat confused, if the problem is that the key code is incorrect, why should it only affect the Ctrl+key? Does just pressing W give a W or does it give something else? Also I dont think we can use glfwGetKeyName() according to the glfw docs that returns localized key names and is meant only for display key names to users, so I doubt there is a robust way to map those back to ascii keys. |
To answer the first part of my question -- it does not affect plain w because that is handled by interpret_text_event not interpret_key_event But the problem remains that glfwGetKeyName does not seem very robust. Instead we need to do whatever glfw does to map keycodes to text events. I dont know if there is an API to do that. |
Maybe use interpret_text_event() instead of interpret_key_event() for all key handling? |
Unfortunately, despite what the docs say, the glfw char mods callback is not called if any non-shift modifier keys are pressed, so it cannot be used. Probably this bug needs to be fixed in glfw |
Perhaps this is easier to see if we run the test units from glfw and I simply press "Ctrl+w" with dvorak layout active, this is the output: 00000003 to 1 at 0.876: Key 0x0155 Scancode 0x0025 (LEFT CONTROL) (with no mods) was pressed
00000004 to 1 at 0.956: Key 0x002c Scancode 0x003b (COMMA) (w) (with control) was pressed
00000005 to 1 at 1.025: Key 0x002c Scancode 0x003b (COMMA) (w) (with control) was released
00000006 to 1 at 1.100: Key 0x0155 Scancode 0x0025 (LEFT CONTROL) (with control) was released The code for the above print, I tried to add a bit of comments static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
const char* name = glfwGetKeyName(key, scancode); // This translates to the layout effective final key
if (name)
{
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (%s) (with%s) was %s\n",
counter++, slot->number, glfwGetTime(), key, scancode,
get_key_name(key), // Key continues to be the hardware key ","
name, // This is what we want to support multiple or non-standard layouts
get_mods_name(mods),
get_action_name(action));
}
} You can see it has "COMMA" and "w", COMMA being the hardware key pressed, and "w" being the actual key after the layout translation has been performed. |
I placed a fix on sebosp@802333c if you want to test, it works for me on dvorak and qwerty, but there seems to be a bug and when you switch keyboard it doesn't switch the "name" properly, I may be missing a flag or an invalidation somewhere. |
The problem I have with that patch is that there is no guarantee that glfwGetKeyName() will return actual ascii key names. Since it is supposed to return localised key names, they could be pretty much anything. So using that patch might actually break keyboard input on some systems where it is currently working. |
Thank you, it works! |
I don't want to open a new issue, but I am also having an issue with control+shift key combinations/shortcuts, I have this key mapping in my .vimrc
which indent/undent, move the line down/up. my colemak layout's neio = your qwerty's hjkl I just tested it and it works as it used to, in the suckless terminal, my previous beloved terminal ...that doesn't support Emoji (became a huge deal breaker 😄), because of it's limited by it's not nearly as developed as cairo+pango drawing library. |
kitty's primary goal is reducing CPU usage, not speed. It deliberately debounces resize events, to avoid unneccessary computation while a resize is in progress. As for your issues, I cannot reproduce them. Use the --debug-keyboard option to see what key events are being sent. |
before remaping
and here's the output of
output of |
Expected behavior:
"Ctrl+w" combination usually removes the word before the cursor while on a terminal.
"Ctrl+w" on multiple windows vim session (i.e.
vim -O file1 file2
) allows you to jump between files.What actually happens:
Ctrl+w is being ignored or not handled.
Thank you, keep up the great work!
The text was updated successfully, but these errors were encountered: