mirror of
https://github.com/tmux/tmux.git
synced 2026-09-16 18:21:58 +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);
|
||||
if (options_get_number(global_options, "extended-keys") == 0)
|
||||
return (0);
|
||||
if (options_get_number(global_options, "extended-keys-format") ==
|
||||
EXTENDED_KEYS_KITTY)
|
||||
return ((c->tty.flags & TTY_KKBPUSHED) != 0);
|
||||
if (c->tty.flags & TTY_KKBPUSHED)
|
||||
return (1);
|
||||
return (tty_term_has(c->tty.term, TTYC_ENEKS));
|
||||
}
|
||||
|
||||
|
||||
29
input.c
29
input.c
@@ -162,6 +162,7 @@ static void input_set_state(struct input_ctx *,
|
||||
const struct input_transition *);
|
||||
static void input_reset_cell(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_8(struct input_ctx *, const char *);
|
||||
static void input_osc_9(struct input_ctx *, const char *);
|
||||
@@ -1179,6 +1180,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. */
|
||||
static void printflike(3, 4)
|
||||
input_reply(struct input_ctx *ictx, int add, const char *fmt, ...)
|
||||
@@ -1576,7 +1600,10 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
options_get_number(global_options, "extended-keys-format") !=
|
||||
EXTENDED_KEYS_KITTY)
|
||||
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;
|
||||
case INPUT_CSI_KITTY_SET:
|
||||
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
@@ -4935,6 +4935,13 @@ this feature is disabled and only standard keys are reported.
|
||||
.Pp
|
||||
.Nm
|
||||
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
|
||||
.Ic extkeys
|
||||
feature for the
|
||||
|
||||
@@ -1112,8 +1112,7 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
|
||||
utf8_char uc;
|
||||
|
||||
*size = 0;
|
||||
if (options_get_number(global_options, "extended-keys-format") ==
|
||||
EXTENDED_KEYS_KITTY)
|
||||
if (tty->flags & TTY_KKBPUSHED)
|
||||
return (-1);
|
||||
|
||||
/* First two bytes are always \033[. */
|
||||
|
||||
11
tty.c
11
tty.c
@@ -562,16 +562,21 @@ void
|
||||
tty_update_features(struct tty *tty)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
int extended_keys, format;
|
||||
|
||||
if (tty_apply_features(tty->term))
|
||||
tty_term_apply_overrides(tty->term);
|
||||
|
||||
if (tty_use_margin(tty))
|
||||
tty_putcode(tty, TTYC_ENMG);
|
||||
if (options_get_number(global_options, "extended-keys-format") ==
|
||||
EXTENDED_KEYS_KITTY)
|
||||
extended_keys = options_get_number(global_options, "extended-keys");
|
||||
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));
|
||||
else if (options_get_number(global_options, "extended-keys"))
|
||||
else
|
||||
tty_puts(tty, tty_term_string(tty->term, TTYC_ENEKS));
|
||||
tty_update_kitty(tty, NULL);
|
||||
if (options_get_number(global_options, "focus-events"))
|
||||
|
||||
Reference in New Issue
Block a user