mirror of
https://github.com/tmux/tmux.git
synced 2026-10-13 14:24:28 +00:00
Make Kitty keyboard negotiation per client
This commit is contained in:
@@ -419,9 +419,8 @@ input_key_client_supports_extended(struct client *c, key_code key)
|
|||||||
return (1);
|
return (1);
|
||||||
if (options_get_number(global_options, "extended-keys") == 0)
|
if (options_get_number(global_options, "extended-keys") == 0)
|
||||||
return (0);
|
return (0);
|
||||||
if (options_get_number(global_options, "extended-keys-format") ==
|
if (c->tty.flags & TTY_KKBPUSHED)
|
||||||
EXTENDED_KEYS_KITTY)
|
return (1);
|
||||||
return ((c->tty.flags & TTY_KKBPUSHED) != 0);
|
|
||||||
return (tty_term_has(c->tty.term, TTYC_ENEKS));
|
return (tty_term_has(c->tty.term, TTYC_ENEKS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
29
input.c
29
input.c
@@ -161,6 +161,7 @@ static void input_set_state(struct input_ctx *,
|
|||||||
const struct input_transition *);
|
const struct input_transition *);
|
||||||
static void input_reset_cell(struct input_ctx *);
|
static void input_reset_cell(struct input_ctx *);
|
||||||
static void input_report_current_theme(struct input_ctx *);
|
static void input_report_current_theme(struct input_ctx *);
|
||||||
|
static int input_pane_supports_extended(struct window_pane *);
|
||||||
static void input_osc_4(struct input_ctx *, const char *);
|
static void input_osc_4(struct input_ctx *, const char *);
|
||||||
static void input_osc_8(struct input_ctx *, const char *);
|
static void input_osc_8(struct input_ctx *, const char *);
|
||||||
static void input_osc_9(struct input_ctx *, const char *);
|
static void input_osc_9(struct input_ctx *, const char *);
|
||||||
@@ -1177,6 +1178,29 @@ input_send_reply(struct input_ctx *ictx, const char *reply)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return whether attached tty clients can provide extended keys to a pane. */
|
||||||
|
static int
|
||||||
|
input_pane_supports_extended(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
struct client *c;
|
||||||
|
|
||||||
|
if (wp == NULL)
|
||||||
|
return (1);
|
||||||
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
|
if ((c->flags & (CLIENT_TERMINAL|CLIENT_ATTACHED)) !=
|
||||||
|
(CLIENT_TERMINAL|CLIENT_ATTACHED))
|
||||||
|
continue;
|
||||||
|
if (c->flags &
|
||||||
|
(CLIENT_UNATTACHEDFLAGS|CLIENT_CONTROL|CLIENT_READONLY))
|
||||||
|
continue;
|
||||||
|
if (c->session == NULL || !session_has(c->session, wp->window))
|
||||||
|
continue;
|
||||||
|
if (!input_key_client_supports_extended(c, 0))
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Reply to terminal query. */
|
/* Reply to terminal query. */
|
||||||
static void printflike(3, 4)
|
static void printflike(3, 4)
|
||||||
input_reply(struct input_ctx *ictx, int add, const char *fmt, ...)
|
input_reply(struct input_ctx *ictx, int add, const char *fmt, ...)
|
||||||
@@ -1574,7 +1598,10 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
options_get_number(global_options, "extended-keys-format") !=
|
options_get_number(global_options, "extended-keys-format") !=
|
||||||
EXTENDED_KEYS_KITTY)
|
EXTENDED_KEYS_KITTY)
|
||||||
break;
|
break;
|
||||||
input_reply(ictx, 1, "\033[?%uu", s->kitty_keys.flags);
|
n = s->kitty_keys.flags;
|
||||||
|
if (!input_pane_supports_extended(ictx->wp))
|
||||||
|
n = 0;
|
||||||
|
input_reply(ictx, 1, "\033[?%uu", n);
|
||||||
break;
|
break;
|
||||||
case INPUT_CSI_KITTY_SET:
|
case INPUT_CSI_KITTY_SET:
|
||||||
if (options_get_number(global_options, "extended-keys") == 0 ||
|
if (options_get_number(global_options, "extended-keys") == 0 ||
|
||||||
|
|||||||
103
regress/kitty-keys-clients.sh
Executable file
103
regress/kitty-keys-clients.sh
Executable file
@@ -0,0 +1,103 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Test per-client keyboard protocol negotiation and pane-side fallback.
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
KCONF=$(mktemp)
|
||||||
|
UCONF=$(mktemp)
|
||||||
|
LCONF=$(mktemp)
|
||||||
|
OUT=$(mktemp)
|
||||||
|
TMP=$(mktemp)
|
||||||
|
SOCKETS="testKmc$$ testKka$$ testKua$$ testKrt$$ testKru$$ testKlq$$ testKlu$$"
|
||||||
|
|
||||||
|
printf '%s\n' 'set -g extended-keys on' \
|
||||||
|
'set -g extended-keys-format kitty' >"$KCONF"
|
||||||
|
printf '%s\n' 'set -g extended-keys on' \
|
||||||
|
'set -g extended-keys-format csi-u' >"$UCONF"
|
||||||
|
printf '%s\n' 'set -g extended-keys off' >"$LCONF"
|
||||||
|
|
||||||
|
cleanup()
|
||||||
|
{
|
||||||
|
rm -f "$KCONF" "$UCONF" "$LCONF" "$OUT" "$TMP"
|
||||||
|
for socket in $SOCKETS; do
|
||||||
|
$TEST_TMUX -L"$socket" kill-server 2>/dev/null
|
||||||
|
done
|
||||||
|
}
|
||||||
|
trap cleanup 0 1 15
|
||||||
|
|
||||||
|
wait_for_mode()
|
||||||
|
{
|
||||||
|
tmux=$1
|
||||||
|
wanted=$2
|
||||||
|
i=0
|
||||||
|
while [ "$($tmux display-message -pt: '#{pane_key_mode}')" != "$wanted" ] &&
|
||||||
|
[ "$i" -lt 50 ]; do
|
||||||
|
sleep 0.1
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
[ "$($tmux display-message -pt: '#{pane_key_mode}')" = "$wanted" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_output()
|
||||||
|
{
|
||||||
|
i=0
|
||||||
|
while [ ! -s "$1" ] && [ "$i" -lt 50 ]; do
|
||||||
|
sleep 0.1
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
[ -s "$1" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
# A server preferring Kitty must negotiate each client independently.
|
||||||
|
M="$TEST_TMUX -LtestKmc$$ -f$KCONF"
|
||||||
|
KA="$TEST_TMUX -LtestKka$$ -f$KCONF"
|
||||||
|
UA="$TEST_TMUX -LtestKua$$ -f$UCONF"
|
||||||
|
$M new-session -d -x80 -y24 -s kitty || exit 1
|
||||||
|
$M new-session -d -x80 -y24 -s csiu || exit 1
|
||||||
|
$KA new-session -d -x80 -y24 "$M attach-session -t kitty" || exit 1
|
||||||
|
$UA new-session -d -x80 -y24 "$M attach-session -t csiu" || exit 1
|
||||||
|
wait_for_mode "$KA" 'Kitty 1' || exit 1
|
||||||
|
wait_for_mode "$UA" 'Ext 2' || exit 1
|
||||||
|
|
||||||
|
uc=$($M list-clients -F '#{client_name} #{client_session}' |
|
||||||
|
awk '$2 == "csiu" { print $1 }')
|
||||||
|
[ -n "$uc" ] || exit 1
|
||||||
|
$M command-prompt -t"$uc" -k 'display-message -pl "%%"' >"$TMP" &
|
||||||
|
pid=$!
|
||||||
|
sleep 0.2
|
||||||
|
$UA send-keys 'Escape [97;5u'
|
||||||
|
wait "$pid"
|
||||||
|
[ "$(tr -d '[:space:]' <"$TMP")" = 'C-a' ] || exit 1
|
||||||
|
$KA kill-server 2>/dev/null
|
||||||
|
$UA kill-server 2>/dev/null
|
||||||
|
$M kill-server 2>/dev/null
|
||||||
|
|
||||||
|
# Standard extended input must be translated for a Kitty-requesting pane.
|
||||||
|
: >"$OUT"
|
||||||
|
R="$TEST_TMUX -LtestKrt$$ -f$KCONF"
|
||||||
|
RU="$TEST_TMUX -LtestKru$$ -f$UCONF"
|
||||||
|
$R new-session -d -x80 -y24 \
|
||||||
|
"stty raw -echo; printf '\033[>1u'; dd bs=1 count=7 2>/dev/null | od -An -v -t x1 >'$OUT'; sleep 5" || exit 1
|
||||||
|
$RU new-session -d -x80 -y24 "$R attach-session" || exit 1
|
||||||
|
wait_for_mode "$RU" 'Ext 2' || exit 1
|
||||||
|
$RU send-keys C-a
|
||||||
|
wait_for_output "$OUT" || exit 1
|
||||||
|
[ "$(tr -d ' \n' <"$OUT")" = '1b5b39373b3575' ] || exit 1
|
||||||
|
$RU kill-server 2>/dev/null
|
||||||
|
$R kill-server 2>/dev/null
|
||||||
|
|
||||||
|
# Do not report Kitty active when an attached client only supports VT10x.
|
||||||
|
: >"$OUT"
|
||||||
|
printf '%s\n' "set -as terminal-overrides ',*:Eneks@:Dseks@'" >>"$KCONF"
|
||||||
|
LQ="$TEST_TMUX -LtestKlq$$ -f$KCONF"
|
||||||
|
LU="$TEST_TMUX -LtestKlu$$ -f$LCONF"
|
||||||
|
$LQ new-session -d -x80 -y24 \
|
||||||
|
"stty raw -echo; sleep 2; printf '\033[>1u\033[?u'; dd bs=1 count=5 2>/dev/null | od -An -v -t x1 >'$OUT'; sleep 5" || exit 1
|
||||||
|
$LU new-session -d -x80 -y24 "$LQ attach-session" || exit 1
|
||||||
|
wait_for_output "$OUT" || exit 1
|
||||||
|
[ "$(tr -d ' \n' <"$OUT")" = '1b5b3f3075' ] || exit 1
|
||||||
|
|
||||||
|
exit 0
|
||||||
7
tmux.1
7
tmux.1
@@ -4941,6 +4941,13 @@ this feature is disabled and only standard keys are reported.
|
|||||||
.Pp
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
will always request extended keys itself if the terminal supports them.
|
will always request extended keys itself if the terminal supports them.
|
||||||
|
When the
|
||||||
|
.Ic kitty
|
||||||
|
format is selected, it is preferred separately for each client; clients which
|
||||||
|
do not support it use standard extended keys if available, or standard VT10x
|
||||||
|
keys otherwise.
|
||||||
|
Input from standard extended-key clients is translated to Kitty encoding for
|
||||||
|
applications which have requested it.
|
||||||
See also the
|
See also the
|
||||||
.Ic extkeys
|
.Ic extkeys
|
||||||
feature for the
|
feature for the
|
||||||
|
|||||||
@@ -1122,8 +1122,7 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
|
|||||||
utf8_char uc;
|
utf8_char uc;
|
||||||
|
|
||||||
*size = 0;
|
*size = 0;
|
||||||
if (options_get_number(global_options, "extended-keys-format") ==
|
if (tty->flags & TTY_KKBPUSHED)
|
||||||
EXTENDED_KEYS_KITTY)
|
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
/* First two bytes are always \033[. */
|
/* First two bytes are always \033[. */
|
||||||
|
|||||||
11
tty.c
11
tty.c
@@ -558,16 +558,21 @@ void
|
|||||||
tty_update_features(struct tty *tty)
|
tty_update_features(struct tty *tty)
|
||||||
{
|
{
|
||||||
struct client *c = tty->client;
|
struct client *c = tty->client;
|
||||||
|
int extended_keys, format;
|
||||||
|
|
||||||
if (tty_apply_features(tty->term))
|
if (tty_apply_features(tty->term))
|
||||||
tty_term_apply_overrides(tty->term);
|
tty_term_apply_overrides(tty->term);
|
||||||
|
|
||||||
if (tty_use_margin(tty))
|
if (tty_use_margin(tty))
|
||||||
tty_putcode(tty, TTYC_ENMG);
|
tty_putcode(tty, TTYC_ENMG);
|
||||||
if (options_get_number(global_options, "extended-keys-format") ==
|
extended_keys = options_get_number(global_options, "extended-keys");
|
||||||
EXTENDED_KEYS_KITTY)
|
format = options_get_number(global_options, "extended-keys-format");
|
||||||
|
if (extended_keys == 0 ||
|
||||||
|
(format == EXTENDED_KEYS_KITTY &&
|
||||||
|
(tty->flags & (TTY_HAVEKKB|TTY_KKBSUPPORT)) ==
|
||||||
|
(TTY_HAVEKKB|TTY_KKBSUPPORT)))
|
||||||
tty_puts(tty, tty_term_string(tty->term, TTYC_DSEKS));
|
tty_puts(tty, tty_term_string(tty->term, TTYC_DSEKS));
|
||||||
else if (options_get_number(global_options, "extended-keys"))
|
else
|
||||||
tty_puts(tty, tty_term_string(tty->term, TTYC_ENEKS));
|
tty_puts(tty, tty_term_string(tty->term, TTYC_ENEKS));
|
||||||
tty_update_kitty(tty, NULL);
|
tty_update_kitty(tty, NULL);
|
||||||
if (options_get_number(global_options, "focus-events"))
|
if (options_get_number(global_options, "focus-events"))
|
||||||
|
|||||||
Reference in New Issue
Block a user