From 2a5eba7899a47d3d2445ff9eabcad466a47b04fa Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 2 Jan 2025 10:34:45 +0000 Subject: [PATCH] Check backspace against VERASE earlier before it is translated to an internal key and do not go through the mapping on output. Fixes problems reported by Ben Price in GitHub issue 4284 and by tb@. --- input-keys.c | 25 ++++++++++++++++++------- tty-keys.c | 21 +++++++++++---------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/input-keys.c b/input-keys.c index 69b62edc..fa4e3f8e 100644 --- a/input-keys.c +++ b/input-keys.c @@ -586,12 +586,24 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key) /* Is this backspace? */ if ((key & KEYC_MASK_KEY) == KEYC_BSPACE) { newkey = options_get_number(global_options, "backspace"); - if (newkey == KEYC_BSPACE) - newkey = '\b'; - newkey |= (key & (KEYC_MASK_FLAGS|KEYC_MASK_MODIFIERS)); - log_debug("%s: key 0x%llx is backspace -> 0x%llx", __func__, key, - newkey); - key = newkey; + log_debug("%s: key 0x%llx is backspace -> 0x%llx", __func__, + key, newkey); + if ((key & KEYC_MASK_MODIFIERS) == 0) { + ud.data[0] = 255; + if ((newkey & KEYC_MASK_MODIFIERS) == 0) + ud.data[0] = newkey; + else if ((newkey & KEYC_MASK_MODIFIERS) == KEYC_CTRL) { + newkey &= KEYC_MASK_KEY; + if (newkey >= 'A' && newkey <= 'Z') + ud.data[0] = newkey - 0x40; + else if (newkey >= 'a' && newkey <= 'z') + ud.data[0] = newkey - 0x60; + } + if (ud.data[0] != 255) + input_key_write(__func__, bev, &ud.data[0], 1); + return (0); + } + key = newkey|(key & (KEYC_MASK_FLAGS|KEYC_MASK_MODIFIERS)); } /* Is this backtab? */ @@ -613,7 +625,6 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key) if (!(key & ~KEYC_MASK_KEY)) { if (key == C0_HT || key == C0_CR || - key == C0_BS || key == C0_ESC || (key >= 0x20 && key <= 0x7f)) { ud.data[0] = key; diff --git a/tty-keys.c b/tty-keys.c index e551e726..0de31c5d 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -885,6 +885,17 @@ first_key: if ((key & KEYC_MASK_KEY) == C0_NUL) key = ' ' | KEYC_CTRL | (key & KEYC_META); + /* + * Check for backspace key using termios VERASE - the terminfo + * kbs entry is extremely unreliable, so cannot be safely + * used. termios should have a better idea. + */ + bspace = tty->tio.c_cc[VERASE]; + if (bspace != _POSIX_VDISABLE && key == bspace) { + log_debug("%s: key %#llx is backspace", c->name, key); + key = KEYC_BSPACE; + } + /* * Fix up all C0 control codes that don't have a dedicated key into * corresponding Ctrl keys. Convert characters in the A-Z range into @@ -894,7 +905,6 @@ first_key: if (onlykey < 0x20 && onlykey != C0_HT && onlykey != C0_CR && - onlykey != C0_BS && onlykey != C0_ESC) { onlykey |= 0x40; if (onlykey >= 'A' && onlykey <= 'Z') @@ -936,15 +946,6 @@ partial_key: complete_key: log_debug("%s: complete key %.*s %#llx", c->name, (int)size, buf, key); - /* - * Check for backspace key using termios VERASE - the terminfo - * kbs entry is extremely unreliable, so cannot be safely - * used. termios should have a better idea. - */ - bspace = tty->tio.c_cc[VERASE]; - if (bspace != _POSIX_VDISABLE && (key & KEYC_MASK_KEY) == bspace) - key = (key & KEYC_MASK_MODIFIERS)|KEYC_BSPACE; - /* Remove key timer. */ if (event_initialized(&tty->key_timer)) evtimer_del(&tty->key_timer);