mirror of
https://github.com/tmux/tmux.git
synced 2026-10-09 19:54:22 +00:00
Fix Kitty key encoding: legacy fallback, F3, case, send-keys drop.
This commit is contained in:
@@ -132,10 +132,13 @@ cmd_send_keys_inject_string(struct cmdq_item *item, struct cmdq_item *after,
|
|||||||
if (!literal) {
|
if (!literal) {
|
||||||
key = key_string_lookup_string(s);
|
key = key_string_lookup_string(s);
|
||||||
if (key != KEYC_NONE && key != KEYC_UNKNOWN) {
|
if (key != KEYC_NONE && key != KEYC_UNKNOWN) {
|
||||||
|
/*
|
||||||
|
* A recognized key name that the pane could not
|
||||||
|
* encode is dropped, not typed as literal text.
|
||||||
|
*/
|
||||||
after = cmd_send_keys_inject_key(item, after, args,
|
after = cmd_send_keys_inject_key(item, after, args,
|
||||||
key);
|
key);
|
||||||
if (after != NULL)
|
return (after == NULL ? item : after);
|
||||||
return (after);
|
|
||||||
}
|
}
|
||||||
literal = 1;
|
literal = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
13
input-keys.c
13
input-keys.c
@@ -485,6 +485,7 @@ input_key_vt10x(struct bufferevent *bev, key_code key)
|
|||||||
struct utf8_data ud;
|
struct utf8_data ud;
|
||||||
key_code onlykey;
|
key_code onlykey;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
int meta;
|
||||||
static const char *standard_map[2] = {
|
static const char *standard_map[2] = {
|
||||||
"1!9(0)=+;:'\",<.>/-8? 2",
|
"1!9(0)=+;:'\",<.>/-8? 2",
|
||||||
"119900=+;;'',,..\x1f\x1f\x7f\x7f\0\0",
|
"119900=+;;'',,..\x1f\x1f\x7f\x7f\0\0",
|
||||||
@@ -492,14 +493,20 @@ input_key_vt10x(struct bufferevent *bev, key_code key)
|
|||||||
|
|
||||||
log_debug("%s: key in %llx", __func__, key);
|
log_debug("%s: key in %llx", __func__, key);
|
||||||
|
|
||||||
if (key & KEYC_META)
|
/*
|
||||||
input_key_write(__func__, bev, "\033", 1);
|
* Remember whether Meta was set and write its ESC prefix only once
|
||||||
|
* the key below it is known to be encodable, so a key that turns
|
||||||
|
* out to fail does not leave a stray ESC in the pane.
|
||||||
|
*/
|
||||||
|
meta = !!(key & KEYC_META);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There's no way to report modifiers for unicode keys in standard mode
|
* There's no way to report modifiers for unicode keys in standard mode
|
||||||
* so lose the modifiers.
|
* so lose the modifiers.
|
||||||
*/
|
*/
|
||||||
if (KEYC_IS_UNICODE(key)) {
|
if (KEYC_IS_UNICODE(key)) {
|
||||||
|
if (meta)
|
||||||
|
input_key_write(__func__, bev, "\033", 1);
|
||||||
utf8_to_data(key, &ud);
|
utf8_to_data(key, &ud);
|
||||||
input_key_write(__func__, bev, ud.data, ud.size);
|
input_key_write(__func__, bev, ud.data, ud.size);
|
||||||
return (0);
|
return (0);
|
||||||
@@ -536,6 +543,8 @@ input_key_vt10x(struct bufferevent *bev, key_code key)
|
|||||||
|
|
||||||
log_debug("%s: key out %llx", __func__, key);
|
log_debug("%s: key out %llx", __func__, key);
|
||||||
|
|
||||||
|
if (meta)
|
||||||
|
input_key_write(__func__, bev, "\033", 1);
|
||||||
ud.data[0] = key & 0x7f;
|
ud.data[0] = key & 0x7f;
|
||||||
input_key_write(__func__, bev, &ud.data[0], 1);
|
input_key_write(__func__, bev, &ud.data[0], 1);
|
||||||
return (0);
|
return (0);
|
||||||
|
|||||||
@@ -250,11 +250,23 @@ input_key_kitty(struct screen *s, struct bufferevent *bev, key_code key)
|
|||||||
ikk = input_kitty_lookup(key);
|
ikk = input_kitty_lookup(key);
|
||||||
if (ikk != NULL) {
|
if (ikk != NULL) {
|
||||||
if ((flags & KITTY_KEY_REPORT_ALL) == 0) {
|
if ((flags & KITTY_KEY_REPORT_ALL) == 0) {
|
||||||
if (ikk->key == C0_CR || ikk->key == C0_HT ||
|
/*
|
||||||
ikk->key == KEYC_BSPACE)
|
* Enter, Tab and Backspace stay in legacy form only
|
||||||
|
* when unmodified, so a plain Enter still works after
|
||||||
|
* a crash, but a modified one is disambiguated.
|
||||||
|
*/
|
||||||
|
if ((ikk->key == C0_CR || ikk->key == C0_HT ||
|
||||||
|
ikk->key == KEYC_BSPACE) && modifiers == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A modified F3 in legacy form ("\033[1;mR") is
|
||||||
|
* indistinguishable from a cursor position report,
|
||||||
|
* so it must always be disambiguated too.
|
||||||
|
*/
|
||||||
if (ikk->final != 'u' &&
|
if (ikk->final != 'u' &&
|
||||||
(modifiers & (KEYC_SUPER|KEYC_HYPER)) == 0)
|
(modifiers & (KEYC_SUPER|KEYC_HYPER)) == 0 &&
|
||||||
|
(ikk->key != KEYC_F3 || modifiers == 0))
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
number = ikk->number;
|
number = ikk->number;
|
||||||
@@ -296,8 +308,10 @@ input_key_kitty(struct screen *s, struct bufferevent *bev, key_code key)
|
|||||||
number = onlykey;
|
number = onlykey;
|
||||||
else
|
else
|
||||||
return (-1);
|
return (-1);
|
||||||
if ((key & KEYC_SHIFT) && number >= 'A' && number <= 'Z')
|
if (number >= 'A' && number <= 'Z') {
|
||||||
number += 'a' - 'A';
|
number += 'a' - 'A';
|
||||||
|
key |= KEYC_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
modifier = input_kitty_modifiers(key);
|
modifier = input_kitty_modifiers(key);
|
||||||
if (modifier == 1)
|
if (modifier == 1)
|
||||||
|
|||||||
@@ -104,5 +104,58 @@ $TMUX respawn-pane -k -t: \
|
|||||||
wait_for_output
|
wait_for_output
|
||||||
check_output 1b5b3f31751b5b3f30751b5b3f38751b5b3f3175
|
check_output 1b5b3f31751b5b3f30751b5b3f38751b5b3f3175
|
||||||
|
|
||||||
|
: >"$OUT"
|
||||||
|
# Modified Enter, Tab and Backspace are disambiguated even under flag 1;
|
||||||
|
# only the unmodified keys stay in legacy form.
|
||||||
|
$TMUX respawn-pane -k -t: \
|
||||||
|
"stty raw -echo; printf '\033[>1u'; dd bs=1 count=7 2>/dev/null | od -An -v -t x1 >'$OUT'; sleep 5"
|
||||||
|
wait_for_mode 'Kitty 1'
|
||||||
|
$TMUX send-keys -t: S-Enter
|
||||||
|
wait_for_output
|
||||||
|
check_output 1b5b31333b3275
|
||||||
|
|
||||||
|
: >"$OUT"
|
||||||
|
$TMUX respawn-pane -k -t: \
|
||||||
|
"stty raw -echo; printf '\033[>1u'; dd bs=1 count=1 2>/dev/null | od -An -v -t x1 >'$OUT'; sleep 5"
|
||||||
|
wait_for_mode 'Kitty 1'
|
||||||
|
$TMUX send-keys -t: Enter
|
||||||
|
wait_for_output
|
||||||
|
check_output 0d
|
||||||
|
|
||||||
|
: >"$OUT"
|
||||||
|
# An unshifted uppercase letter, as delivered by a legacy terminal or by
|
||||||
|
# send-keys, is reported as the lowercase code point plus Shift.
|
||||||
|
$TMUX respawn-pane -k -t: \
|
||||||
|
"stty raw -echo; printf '\033[>9u'; dd bs=1 count=7 2>/dev/null | od -An -v -t x1 >'$OUT'; sleep 5"
|
||||||
|
wait_for_mode 'Kitty 9'
|
||||||
|
$TMUX send-keys -t: A
|
||||||
|
wait_for_output
|
||||||
|
check_output 1b5b39373b3275
|
||||||
|
|
||||||
|
: >"$OUT"
|
||||||
|
# A modified F3 must use the unambiguous form even under flag 1 alone, since
|
||||||
|
# its legacy form ("CSI 1;mR") cannot be told apart from a cursor position
|
||||||
|
# report.
|
||||||
|
$TMUX respawn-pane -k -t: \
|
||||||
|
"stty raw -echo; printf '\033[>1u'; dd bs=1 count=7 2>/dev/null | od -An -v -t x1 >'$OUT'; sleep 5"
|
||||||
|
wait_for_mode 'Kitty 1'
|
||||||
|
$TMUX send-keys -t: S-F3
|
||||||
|
wait_for_output
|
||||||
|
check_output 1b5b31333b327e
|
||||||
|
|
||||||
|
# The following are not specific to the Kitty protocol, but were found by
|
||||||
|
# the same testing: send-keys must drop a key name it cannot encode for the
|
||||||
|
# pane's current mode rather than typing the name itself as text, and must
|
||||||
|
# not leave a stray Escape behind while deciding that.
|
||||||
|
: >"$OUT"
|
||||||
|
$TMUX respawn-pane -k -t: \
|
||||||
|
"stty raw -echo; timeout 2 dd bs=1 2>/dev/null | od -An -v -t x1 >'$OUT'"
|
||||||
|
sleep 0.3
|
||||||
|
for key in C-Escape C-BSpace M-C-BSpace; do
|
||||||
|
$TMUX send-keys -t: "$key"
|
||||||
|
done
|
||||||
|
sleep 2.3
|
||||||
|
check_output ''
|
||||||
|
|
||||||
$TMUX kill-server 2>/dev/null
|
$TMUX kill-server 2>/dev/null
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
Reference in New Issue
Block a user