Make cursor keys work better

This commit is contained in:
Přemysl Eric Janouch 2015-07-25 19:05:00 +02:00
parent 477f732bc3
commit dc7b9efd71
1 changed files with 48 additions and 34 deletions

View File

@ -554,17 +554,28 @@ register_keys (void)
for (i = 0; i < NCSIFUNCS; i++) for (i = 0; i < NCSIFUNCS; i++)
csifuncs[i].sym = TERMO_SYM_UNKNOWN; csifuncs[i].sym = TERMO_SYM_UNKNOWN;
register_csi_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_UP, 'A'); // Cursor keys handling; there's some weird, weird stuff going on here:
register_csi_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_DOWN, 'B'); //
register_csi_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_RIGHT, 'C'); // rxvt-based terminals should output SS3 A/B/C/D for C-S-arrow keys;
register_csi_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_LEFT, 'D'); // rxvt-unicode however only seems to output Shift codes.
register_csi_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_BEGIN, 'E'); //
register_csi_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_END, 'F'); // xterm, PuTTY, tmux output SS3 A/B/C/D for normal arrow keys when
register_csi_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_HOME, 'H'); // terminfo start string has been written -- it gets eaten by the terminfo
register_csi_ss3 (TERMO_TYPE_FUNCTION, 1, 'P'); // driver then, usually. To the contrary, CSI A/B/C/D is used for Ctrl.
register_csi_ss3 (TERMO_TYPE_FUNCTION, 2, 'Q');
register_csi_ss3 (TERMO_TYPE_FUNCTION, 3, 'R'); register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_UP, 0, 'A');
register_csi_ss3 (TERMO_TYPE_FUNCTION, 4, 'S'); register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_DOWN, 0, 'B');
register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_RIGHT, 0, 'C');
register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_LEFT, 0, 'D');
register_csi_ss3_full
(TERMO_TYPE_KEYSYM, TERMO_SYM_UP, TERMO_KEYMOD_CTRL, 0, 'A');
register_csi_ss3_full
(TERMO_TYPE_KEYSYM, TERMO_SYM_DOWN, TERMO_KEYMOD_CTRL, 0, 'B');
register_csi_ss3_full
(TERMO_TYPE_KEYSYM, TERMO_SYM_RIGHT, TERMO_KEYMOD_CTRL, 0, 'C');
register_csi_ss3_full
(TERMO_TYPE_KEYSYM, TERMO_SYM_LEFT, TERMO_KEYMOD_CTRL, 0, 'D');
// Handle Shift-modified rxvt cursor keys (CSI a, CSI b, CSI c, CSI d) // Handle Shift-modified rxvt cursor keys (CSI a, CSI b, CSI c, CSI d)
csi_handlers['a' - 0x20] = &handle_csi_cursor; csi_handlers['a' - 0x20] = &handle_csi_cursor;
@ -578,13 +589,15 @@ register_keys (void)
register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_RIGHT, TERMO_KEYMOD_CTRL, 'c'); register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_RIGHT, TERMO_KEYMOD_CTRL, 'c');
register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_LEFT, TERMO_KEYMOD_CTRL, 'd'); register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_LEFT, TERMO_KEYMOD_CTRL, 'd');
// Unfortunately Ctrl-Shift-modified rxvt cursor keys get eaten up by // End of cursor keys handling
// csi_ss3s as unmodified but rxvt-unicode only seems to output Shift codes
// for them anyway, so it's not a huge loss.
// TODO: change the handling depending on the value of TERM register_csi_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_BEGIN, 'E');
// - rxvt-based terminals use SS3 A/B/C/D for C-S-arrow keys register_csi_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_END, 'F');
// - PuTTY uses SS3 A/B/C/D for something different -> try it out register_csi_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_HOME, 'H');
register_csi_ss3 (TERMO_TYPE_FUNCTION, 1, 'P');
register_csi_ss3 (TERMO_TYPE_FUNCTION, 2, 'Q');
register_csi_ss3 (TERMO_TYPE_FUNCTION, 3, 'R');
register_csi_ss3 (TERMO_TYPE_FUNCTION, 4, 'S');
register_csi_ss3_full (TERMO_TYPE_KEYSYM, TERMO_SYM_TAB, register_csi_ss3_full (TERMO_TYPE_KEYSYM, TERMO_SYM_TAB,
TERMO_KEYMOD_SHIFT, TERMO_KEYMOD_SHIFT, 'Z'); TERMO_KEYMOD_SHIFT, TERMO_KEYMOD_SHIFT, 'Z');
@ -781,13 +794,21 @@ peekkey_ss3 (termo_t *tk, termo_csi_t *csi, size_t introlen,
if (cmd < 0x40 || cmd >= 0x80) if (cmd < 0x40 || cmd >= 0x80)
return TERMO_RES_NONE; return TERMO_RES_NONE;
// First go have a look at SS3-only sequences
key->type = ss3s[cmd - 0x20].type;
key->code.sym = ss3s[cmd - 0x20].sym;
key->modifiers = ss3s[cmd - 0x20].modifier_set;
// If that fails, try our mixed table (is there a reason for it?)
if (key->code.sym == TERMO_SYM_UNKNOWN)
{
key->type = csi_ss3s[cmd - 0x20].type; key->type = csi_ss3s[cmd - 0x20].type;
key->code.sym = csi_ss3s[cmd - 0x20].sym; key->code.sym = csi_ss3s[cmd - 0x20].sym;
key->modifiers = csi_ss3s[cmd - 0x20].modifier_set; key->modifiers = csi_ss3s[cmd - 0x20].modifier_set;
}
if (key->code.sym == TERMO_SYM_UNKNOWN) // If we have a match for a keypad key but user wants to receive them
{ // as characters instead, convert them
if (tk->flags & TERMO_FLAG_CONVERTKP && ss3_kpalts[cmd - 0x20]) else if ((tk->flags & TERMO_FLAG_CONVERTKP && ss3_kpalts[cmd - 0x20]))
{ {
key->type = TERMO_TYPE_KEY; key->type = TERMO_TYPE_KEY;
key->code.codepoint = ss3_kpalts[cmd - 0x20]; key->code.codepoint = ss3_kpalts[cmd - 0x20];
@ -796,13 +817,6 @@ peekkey_ss3 (termo_t *tk, termo_csi_t *csi, size_t introlen,
key->multibyte[0] = key->code.codepoint; key->multibyte[0] = key->code.codepoint;
key->multibyte[1] = 0; key->multibyte[1] = 0;
} }
else
{
key->type = ss3s[cmd - 0x20].type;
key->code.sym = ss3s[cmd - 0x20].sym;
key->modifiers = ss3s[cmd - 0x20].modifier_set;
}
}
if (key->code.sym == TERMO_SYM_UNKNOWN) if (key->code.sym == TERMO_SYM_UNKNOWN)
{ {