Detection, done like sync:

- ESC[?u goes to every VT100-like terminal at attach, whatever the
  options.
- A reply turns on a new kittykeys terminal feature. Users can force
  it on or off with terminal-features kittykeys, including kittykeys@
  to turn it off.
- Changing extended-keys now takes effect immediately for attached
  clients (options.c).

Use, per client, when extended-keys is on: Kitty for clients that have
kittykeys, modifyOtherKeys for clients with extkeys, VT10x otherwise.

Pane side:

- Applications can request either protocol; Kitty wins if one asks for
  both.
- Each application gets what it asked for, whichever client typed the
  key.
- ESC[?u is answered truthfully.
- The per-client gate is gone. window.c and popup.c are simply
  master's versions again.

extended-keys always is back to its master meaning, forcing
modifyOtherKeys mode 1 only. Forcing Kitty on every program would have
sent bash ESC[97;5u for Ctrl-A.

extended-keys-format kitty is still accepted, but now behaves the same
as csi-u.
This commit is contained in:
Michael Grant
2026-09-19 07:32:57 +01:00
parent 7545954d00
commit d85329e5f0
17 changed files with 117 additions and 212 deletions

View File

@@ -1,27 +1,23 @@
#!/bin/sh
# Test per-client keyboard protocol negotiation and pane-side fallback.
# Test per-client keyboard protocol detection and pane-side encoding.
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 on' >"$KCONF"
printf '%s\n' 'set -g extended-keys off' >"$LCONF"
cleanup()
{
rm -f "$KCONF" "$UCONF" "$LCONF" "$OUT" "$TMP"
rm -f "$KCONF" "$LCONF" "$OUT" "$TMP"
for socket in $SOCKETS; do
$TEST_TMUX -L"$socket" kill-server 2>/dev/null
done
@@ -78,16 +74,17 @@ wait_for_client_mode()
[ "$(client_mode "$tmux" "$session")" = "$wanted" ]
}
# A server preferring Kitty must negotiate each client independently.
# Each client must be negotiated independently. A tmux with extended-keys off
# stands in for a terminal without Kitty keys, since it does not answer the
# query.
M="$TEST_TMUX -LtestKmc$$ -f$KCONF"
KA="$TEST_TMUX -LtestKka$$ -f$KCONF"
UA="$TEST_TMUX -LtestKua$$ -f$UCONF"
UA="$TEST_TMUX -LtestKua$$ -f$LCONF"
$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
# Each client must report the protocol its own terminal negotiated.
wait_for_client_mode "$M" kitty 'Kitty 1' || exit 1
@@ -99,7 +96,7 @@ uc=$($M list-clients -F '#{client_name} #{client_session}' |
$M command-prompt -t"$uc" -k 'display-message -pl "%%"' >"$TMP" &
pid=$!
sleep 0.2
$UA send-keys 'Escape [97;5u'
$UA send-keys Escape '[97;5u'
wait "$pid"
[ "$(tr -d '[:space:]' <"$TMP")" = 'C-a' ] || exit 1
@@ -117,11 +114,10 @@ $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"
RU="$TEST_TMUX -LtestKru$$ -f$LCONF"
$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
wait_for_client_mode "$R" '' 'Ext' || exit 1
$RU send-keys C-a
wait_for_output "$OUT" || exit 1
@@ -129,16 +125,22 @@ wait_for_output "$OUT" || 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.
# An application is told the Kitty flags it asked for even when a client that
# only supports VT10x is attached, and keys from that client are encoded as it
# asked.
: >"$OUT"
: >"$TMP"
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
"stty raw -echo; sleep 2; printf '\033[>1u\033[?u'; dd bs=1 count=5 2>/dev/null | od -An -v -t x1 >'$OUT'; dd bs=1 count=7 2>/dev/null | od -An -v -t x1 >'$TMP'; 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
[ "$(tr -d ' \n' <"$OUT")" = '1b5b3f3175' ] || exit 1
wait_for_client_mode "$LQ" '' 'VT10x' || exit 1
$LU send-keys C-a
wait_for_output "$TMP" || exit 1
[ "$(tr -d ' \n' <"$TMP")" = '1b5b39373b3575' ] || exit 1
exit 0

View File

@@ -12,8 +12,7 @@ TERM=screen
CONF=$(mktemp)
TMP=$(mktemp)
printf '%s\n' 'set -g extended-keys on' \
'set -g extended-keys-format kitty' >"$CONF"
printf '%s\n' 'set -g extended-keys on' >"$CONF"
TMUX="$TEST_TMUX -LtestKIA$$ -f$CONF"
TMUX2="$TEST_TMUX -LtestKIB$$ -f$CONF"
@@ -44,7 +43,9 @@ assert_key()
$TMUX2 command-prompt -k 'display-message -pl "%%"' >"$TMP" &
sleep 0.15
$TMUX send-keys $keys
# Send raw bytes so the outer tmux does not encode them itself.
raw=$(printf '%s' "$keys" | sed -e 's/Escape /\\033/g' -e 's/ //g')
$TMUX send-keys -H $(printf "$raw" | od -An -v -t x1)
wait
actual=$(tr -d '[:space:]' <"$TMP")
@@ -62,10 +63,6 @@ if ! wait_for_mode 'Kitty 1'; then
exit 1
fi
# The handshake is done, so stop the outer tmux encoding the raw sequences
# below as Kitty keys itself.
$TMUX set-option -g extended-keys-format csi-u
# Modifiers, including the Kitty-only Super and Hyper.
assert_key 'Escape [97;2u' 'S-a'
assert_key 'Escape [97;3u' 'M-a'

View File

@@ -13,8 +13,7 @@ TMUX="$TEST_TMUX -LtestK$$ -f$CONF"
trap 'rm -f "$CONF" "$OUT"; $TMUX kill-server 2>/dev/null' 0 1 15
printf '%s\n' 'set -g extended-keys on' \
'set -g extended-keys-format kitty' >"$CONF"
printf '%s\n' 'set -g extended-keys on' >"$CONF"
wait_for_output()
{
@@ -90,11 +89,13 @@ wait_for_output
check_output 1b5b3f31751b5b3f3075
: >"$OUT"
# "always" forces modifyOtherKeys mode 1, not Kitty keys.
$TMUX set-option -g extended-keys always
$TMUX respawn-pane -k -t: \
"stty raw -echo; printf '\033[>0u\033[?u'; dd bs=1 count=5 2>/dev/null | od -An -v -t x1 >'$OUT'; sleep 5"
wait_for_output
check_output 1b5b3f3175
check_output 1b5b3f3075
wait_for_mode 'Ext 1'
$TMUX set-option -g extended-keys on
: >"$OUT"