From 740a89b77fdfcf88caa148ac7aa17552ea8c7e44 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 27 Feb 2018 08:46:09 +0530 Subject: [PATCH] Treat Ctrl+Alt+letter as Esc,Ctrl+letter Follows the behavior of some other terminals and is better than generating nothing, since apparently there are some terminal programs that use these keys. Fixes #345 --- kitty/keys.h | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++ kitty/keys.py | 4 + 2 files changed, 212 insertions(+) diff --git a/kitty/keys.h b/kitty/keys.h index 342c43087..c6e045585 100644 --- a/kitty/keys.h +++ b/kitty/keys.h @@ -1126,6 +1126,58 @@ key_lookup(uint8_t key, KeyboardMode mode, uint8_t mods, uint8_t action) { } // end switch(key) case 0x6: switch(key & 0x7f) { default: return NULL; + case 18: // A + return "\x02\x1b\x01"; + case 19: // B + return "\x02\x1b\x02"; + case 20: // C + return "\x02\x1b\x03"; + case 21: // D + return "\x02\x1b\x04"; + case 22: // E + return "\x02\x1b\x05"; + case 23: // F + return "\x02\x1b\x06"; + case 24: // G + return "\x02\x1b\x07"; + case 25: // H + return "\x02\x1b\x08"; + case 26: // I + return "\x02\x1b\x09"; + case 27: // J + return "\x02\x1b\x0a"; + case 28: // K + return "\x02\x1b\x0b"; + case 29: // L + return "\x02\x1b\x0c"; + case 30: // M + return "\x02\x1b\x0d"; + case 31: // N + return "\x02\x1b\x0e"; + case 32: // O + return "\x02\x1b\x0f"; + case 33: // P + return "\x02\x1b\x10"; + case 34: // Q + return "\x02\x1b\x11"; + case 35: // R + return "\x02\x1b\x12"; + case 36: // S + return "\x02\x1b\x13"; + case 37: // T + return "\x02\x1b\x14"; + case 38: // U + return "\x02\x1b\x15"; + case 39: // V + return "\x02\x1b\x16"; + case 40: // W + return "\x02\x1b\x17"; + case 41: // X + return "\x02\x1b\x18"; + case 42: // Y + return "\x02\x1b\x19"; + case 43: // Z + return "\x02\x1b\x1a"; case 50: // ESCAPE return "\x01\x1b"; case 51: // ENTER @@ -2332,6 +2384,58 @@ key_lookup(uint8_t key, KeyboardMode mode, uint8_t mods, uint8_t action) { } // end switch(key) case 0x6: switch(key & 0x7f) { default: return NULL; + case 18: // A + return "\x02\x1b\x01"; + case 19: // B + return "\x02\x1b\x02"; + case 20: // C + return "\x02\x1b\x03"; + case 21: // D + return "\x02\x1b\x04"; + case 22: // E + return "\x02\x1b\x05"; + case 23: // F + return "\x02\x1b\x06"; + case 24: // G + return "\x02\x1b\x07"; + case 25: // H + return "\x02\x1b\x08"; + case 26: // I + return "\x02\x1b\x09"; + case 27: // J + return "\x02\x1b\x0a"; + case 28: // K + return "\x02\x1b\x0b"; + case 29: // L + return "\x02\x1b\x0c"; + case 30: // M + return "\x02\x1b\x0d"; + case 31: // N + return "\x02\x1b\x0e"; + case 32: // O + return "\x02\x1b\x0f"; + case 33: // P + return "\x02\x1b\x10"; + case 34: // Q + return "\x02\x1b\x11"; + case 35: // R + return "\x02\x1b\x12"; + case 36: // S + return "\x02\x1b\x13"; + case 37: // T + return "\x02\x1b\x14"; + case 38: // U + return "\x02\x1b\x15"; + case 39: // V + return "\x02\x1b\x16"; + case 40: // W + return "\x02\x1b\x17"; + case 41: // X + return "\x02\x1b\x18"; + case 42: // Y + return "\x02\x1b\x19"; + case 43: // Z + return "\x02\x1b\x1a"; case 50: // ESCAPE return "\x01\x1b"; case 51: // ENTER @@ -3546,6 +3650,58 @@ key_lookup(uint8_t key, KeyboardMode mode, uint8_t mods, uint8_t action) { } // end switch(key) case 0x6: switch(key & 0x7f) { default: return NULL; + case 18: // A + return "\x02\x1b\x01"; + case 19: // B + return "\x02\x1b\x02"; + case 20: // C + return "\x02\x1b\x03"; + case 21: // D + return "\x02\x1b\x04"; + case 22: // E + return "\x02\x1b\x05"; + case 23: // F + return "\x02\x1b\x06"; + case 24: // G + return "\x02\x1b\x07"; + case 25: // H + return "\x02\x1b\x08"; + case 26: // I + return "\x02\x1b\x09"; + case 27: // J + return "\x02\x1b\x0a"; + case 28: // K + return "\x02\x1b\x0b"; + case 29: // L + return "\x02\x1b\x0c"; + case 30: // M + return "\x02\x1b\x0d"; + case 31: // N + return "\x02\x1b\x0e"; + case 32: // O + return "\x02\x1b\x0f"; + case 33: // P + return "\x02\x1b\x10"; + case 34: // Q + return "\x02\x1b\x11"; + case 35: // R + return "\x02\x1b\x12"; + case 36: // S + return "\x02\x1b\x13"; + case 37: // T + return "\x02\x1b\x14"; + case 38: // U + return "\x02\x1b\x15"; + case 39: // V + return "\x02\x1b\x16"; + case 40: // W + return "\x02\x1b\x17"; + case 41: // X + return "\x02\x1b\x18"; + case 42: // Y + return "\x02\x1b\x19"; + case 43: // Z + return "\x02\x1b\x1a"; case 50: // ESCAPE return "\x01\x1b"; case 51: // ENTER @@ -4752,6 +4908,58 @@ key_lookup(uint8_t key, KeyboardMode mode, uint8_t mods, uint8_t action) { } // end switch(key) case 0x6: switch(key & 0x7f) { default: return NULL; + case 18: // A + return "\x02\x1b\x01"; + case 19: // B + return "\x02\x1b\x02"; + case 20: // C + return "\x02\x1b\x03"; + case 21: // D + return "\x02\x1b\x04"; + case 22: // E + return "\x02\x1b\x05"; + case 23: // F + return "\x02\x1b\x06"; + case 24: // G + return "\x02\x1b\x07"; + case 25: // H + return "\x02\x1b\x08"; + case 26: // I + return "\x02\x1b\x09"; + case 27: // J + return "\x02\x1b\x0a"; + case 28: // K + return "\x02\x1b\x0b"; + case 29: // L + return "\x02\x1b\x0c"; + case 30: // M + return "\x02\x1b\x0d"; + case 31: // N + return "\x02\x1b\x0e"; + case 32: // O + return "\x02\x1b\x0f"; + case 33: // P + return "\x02\x1b\x10"; + case 34: // Q + return "\x02\x1b\x11"; + case 35: // R + return "\x02\x1b\x12"; + case 36: // S + return "\x02\x1b\x13"; + case 37: // T + return "\x02\x1b\x14"; + case 38: // U + return "\x02\x1b\x15"; + case 39: // V + return "\x02\x1b\x16"; + case 40: // W + return "\x02\x1b\x17"; + case 41: // X + return "\x02\x1b\x18"; + case 42: // Y + return "\x02\x1b\x19"; + case 43: // Z + return "\x02\x1b\x1a"; case 50: // ESCAPE return "\x01\x1b"; case 51: // ENTER diff --git a/kitty/keys.py b/kitty/keys.py index cd556e07c..46c75dfa1 100644 --- a/kitty/keys.py +++ b/kitty/keys.py @@ -36,6 +36,7 @@ shift_alt_codes = alt_codes.copy() shift_alt_codes[defines.GLFW_KEY_TAB] = key_as_bytes('kcbt') alt_mods = (defines.GLFW_MOD_ALT, defines.GLFW_MOD_SHIFT | defines.GLFW_MOD_ALT) ctrl_shift_mod = defines.GLFW_MOD_SHIFT | defines.GLFW_MOD_CONTROL +ctrl_alt_mod = defines.GLFW_MOD_ALT | defines.GLFW_MOD_CONTROL for kf, kn in { defines.GLFW_KEY_UP: 'kcuu1', @@ -204,6 +205,7 @@ ASCII_C0_SHIFTED = { 'SLASH': b'\x7f', } CTRL_SHIFT_KEYS = {getattr(defines, 'GLFW_KEY_' + k): v for k, v in ASCII_C0_SHIFTED.items()} +CTRL_ALT_KEYS = {getattr(defines, 'GLFW_KEY_' + k) for k in string.ascii_uppercase} def key_to_bytes(key, smkx, extended, mods, action): @@ -222,6 +224,8 @@ def key_to_bytes(key, smkx, extended, mods, action): m = UN_SHIFTED_PRINTABLE if mods == defines.GLFW_MOD_ALT else SHIFTED_PRINTABLE data.append(0o33) data.extend(m[key]) + elif mods == ctrl_alt_mod and key in CTRL_ALT_KEYS: + data.append(0x1b), data.extend(control_codes[key]) else: key_map = cursor_key_mode_map[smkx] x = key_map.get(key)