mirror of
https://github.com/tmux/tmux.git
synced 2026-09-19 11:28:08 +00:00
Compare commits
1 Commits
kitty-keyb
...
kitty-keys
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c96fde851 |
16
CHANGES
16
CHANGES
@@ -111,14 +111,14 @@ CHANGES FROM 3.7c TO 3.8
|
||||
|
||||
* Change show-options and show-hooks to use formats and add a -F flag to each.
|
||||
|
||||
* Add support for the Kitty keyboard protocol, selected with a new kitty
|
||||
value for the extended-keys-format option. This can report the Super and
|
||||
Hyper modifiers (key name prefixes s- and H-) as well as Control, Meta
|
||||
and Shift. The protocol is negotiated separately with each client, so
|
||||
terminals with different capabilities may be attached at the same time;
|
||||
clients without it use standard extended keys, or VT10x keys if those
|
||||
are also unavailable, and their input is translated for applications
|
||||
which have asked for Kitty encoding.
|
||||
* Add support for the Kitty keyboard protocol. When extended-keys is on,
|
||||
tmux uses it with terminals which support it, detected when a client
|
||||
attaches or set with a new kittykeys terminal feature, and standard
|
||||
extended keys or VT10x keys with other terminals, so terminals with
|
||||
different capabilities may be attached at the same time. Programs inside
|
||||
tmux may ask for either the Kitty protocol or modifyOtherKeys and get keys
|
||||
in the form they asked for. The Kitty protocol can report the Super and
|
||||
Hyper modifiers (key name prefixes s- and H-).
|
||||
|
||||
* Add a client_key_mode format giving the extended key reporting mode in
|
||||
use for a client, alongside the existing pane_key_mode for a pane.
|
||||
|
||||
11
format.c
11
format.c
@@ -1635,11 +1635,9 @@ format_cb_client_key_mode(struct format_tree *ft)
|
||||
}
|
||||
|
||||
/* This mirrors the choice made in tty_update_features(). */
|
||||
kitty = ((c->tty.flags & (TTY_HAVEKKB|TTY_KKBSUPPORT)) ==
|
||||
(TTY_HAVEKKB|TTY_KKBSUPPORT));
|
||||
kitty = ((c->tty.term->flags & TERM_KITTYKEYS) != 0);
|
||||
eks = (options_get_number(global_options, "extended-keys") != 0);
|
||||
if (kitty && options_get_number(global_options,
|
||||
"extended-keys-format") == EXTENDED_KEYS_KITTY)
|
||||
if (kitty)
|
||||
eks = 0;
|
||||
if (eks && tty_term_has(c->tty.term, TTYC_ENEKS))
|
||||
mode = "Ext";
|
||||
@@ -2527,10 +2525,7 @@ format_cb_pane_key_mode(struct format_tree *ft)
|
||||
char *s;
|
||||
|
||||
if (ft->wp != NULL && ft->wp->screen != NULL) {
|
||||
if (options_get_number(global_options, "extended-keys-format") ==
|
||||
EXTENDED_KEYS_KITTY) {
|
||||
if (ft->wp->screen->kitty_keys.flags == 0)
|
||||
return (xstrdup("VT10x"));
|
||||
if (ft->wp->screen->kitty_keys.flags != 0) {
|
||||
xasprintf(&s, "Kitty %u",
|
||||
ft->wp->screen->kitty_keys.flags);
|
||||
return (s);
|
||||
|
||||
29
input-keys.c
29
input-keys.c
@@ -395,8 +395,7 @@ input_key_build(void)
|
||||
|
||||
/* Translate a key code into an output key sequence for a pane. */
|
||||
int
|
||||
input_key_pane(struct window_pane *wp, key_code key, struct mouse_event *m,
|
||||
int extended_encoding)
|
||||
input_key_pane(struct window_pane *wp, key_code key, struct mouse_event *m)
|
||||
{
|
||||
if (log_get_level() != 0) {
|
||||
log_debug("writing key 0x%llx (%s) to %%%u", key,
|
||||
@@ -408,20 +407,7 @@ input_key_pane(struct window_pane *wp, key_code key, struct mouse_event *m,
|
||||
input_key_mouse(wp, m);
|
||||
return (0);
|
||||
}
|
||||
return (input_key(wp->screen, wp->event, key, extended_encoding));
|
||||
}
|
||||
|
||||
/* Return whether a key may use the configured extended encoding. */
|
||||
int
|
||||
input_key_client_supports_extended(struct client *c, key_code key)
|
||||
{
|
||||
if (c == NULL || (key & KEYC_SENT))
|
||||
return (1);
|
||||
if (options_get_number(global_options, "extended-keys") == 0)
|
||||
return (0);
|
||||
if (c->tty.flags & TTY_KKBPUSHED)
|
||||
return (1);
|
||||
return (tty_term_has(c->tty.term, TTYC_ENEKS));
|
||||
return (input_key(wp->screen, wp->event, key));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -586,8 +572,7 @@ input_key_mode1(struct bufferevent *bev, key_code key)
|
||||
|
||||
/* Translate a key code into an output key sequence. */
|
||||
int
|
||||
input_key(struct screen *s, struct bufferevent *bev, key_code key,
|
||||
int extended_encoding)
|
||||
input_key(struct screen *s, struct bufferevent *bev, key_code key)
|
||||
{
|
||||
struct input_key_entry *ike = NULL;
|
||||
key_code newkey;
|
||||
@@ -604,9 +589,8 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key,
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (extended_encoding &&
|
||||
options_get_number(global_options, "extended-keys-format") ==
|
||||
EXTENDED_KEYS_KITTY && input_key_kitty(s, bev, key) == 0)
|
||||
/* Kitty keys take precedence if the application asked for them. */
|
||||
if (input_key_kitty(s, bev, key) == 0)
|
||||
return (0);
|
||||
|
||||
/* Is this backspace? */
|
||||
@@ -700,8 +684,7 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key,
|
||||
}
|
||||
if (key & (KEYC_SUPER|KEYC_HYPER))
|
||||
return (input_key_vt10x(bev, key));
|
||||
if (options_get_number(global_options, "extended-keys-format") ==
|
||||
EXTENDED_KEYS_KITTY)
|
||||
if (s->kitty_keys.flags & KITTY_KEY_SUPPORTED)
|
||||
return (input_key_vt10x(bev, key));
|
||||
|
||||
/*
|
||||
|
||||
@@ -145,21 +145,10 @@ static const struct input_kitty_key input_kitty_keys[] = {
|
||||
{ KEYC_ISO_LEVEL5_SHIFT, 57454, 'u' }
|
||||
};
|
||||
|
||||
static u_int
|
||||
input_kitty_default_flags(void)
|
||||
{
|
||||
if (options_get_number(global_options, "extended-keys") == 2 &&
|
||||
options_get_number(global_options, "extended-keys-format") ==
|
||||
EXTENDED_KEYS_KITTY)
|
||||
return (KITTY_KEY_DISAMBIGUATE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
input_kitty_reset(struct screen *s)
|
||||
{
|
||||
memset(&s->kitty_keys, 0, sizeof s->kitty_keys);
|
||||
s->kitty_keys.flags = input_kitty_default_flags();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -186,7 +175,6 @@ input_kitty_set(struct screen *s, u_int flags, int mode)
|
||||
s->kitty_keys.flags &= ~flags;
|
||||
else
|
||||
s->kitty_keys.flags = flags;
|
||||
s->kitty_keys.flags |= input_kitty_default_flags();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -194,8 +182,7 @@ input_kitty_push(struct screen *s, u_int flags)
|
||||
{
|
||||
s->kitty_keys.saved_flags = s->kitty_keys.flags;
|
||||
s->kitty_keys.have_saved = 1;
|
||||
s->kitty_keys.flags = (flags & KITTY_KEY_SUPPORTED)|
|
||||
input_kitty_default_flags();
|
||||
s->kitty_keys.flags = flags & KITTY_KEY_SUPPORTED;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -206,9 +193,8 @@ input_kitty_pop(struct screen *s, u_int count)
|
||||
if (s->kitty_keys.have_saved && count == 1)
|
||||
s->kitty_keys.flags = s->kitty_keys.saved_flags;
|
||||
else
|
||||
s->kitty_keys.flags = input_kitty_default_flags();
|
||||
s->kitty_keys.flags = 0;
|
||||
s->kitty_keys.have_saved = 0;
|
||||
s->kitty_keys.flags |= input_kitty_default_flags();
|
||||
}
|
||||
|
||||
static u_int
|
||||
|
||||
51
input.c
51
input.c
@@ -162,7 +162,6 @@ 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 *);
|
||||
@@ -1180,29 +1179,6 @@ 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, ...)
|
||||
@@ -1557,9 +1533,6 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
screen_write_cursormove(sctx, m - 1, n - 1, 1);
|
||||
break;
|
||||
case INPUT_CSI_MODSET:
|
||||
if (options_get_number(global_options, "extended-keys-format") ==
|
||||
EXTENDED_KEYS_KITTY)
|
||||
break;
|
||||
n = input_get(ictx, 0, 0, 0);
|
||||
if (n != 4)
|
||||
break;
|
||||
@@ -1579,9 +1552,6 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
screen_write_mode_set(sctx, MODE_KEYS_EXTENDED);
|
||||
break;
|
||||
case INPUT_CSI_MODOFF:
|
||||
if (options_get_number(global_options, "extended-keys-format") ==
|
||||
EXTENDED_KEYS_KITTY)
|
||||
break;
|
||||
n = input_get(ictx, 0, 0, 0);
|
||||
if (n != 4)
|
||||
break;
|
||||
@@ -1596,19 +1566,12 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
screen_write_mode_set(sctx, MODE_KEYS_EXTENDED);
|
||||
break;
|
||||
case INPUT_CSI_KITTY_QUERY:
|
||||
if (options_get_number(global_options, "extended-keys") == 0 ||
|
||||
options_get_number(global_options, "extended-keys-format") !=
|
||||
EXTENDED_KEYS_KITTY)
|
||||
if (options_get_number(global_options, "extended-keys") == 0)
|
||||
break;
|
||||
n = s->kitty_keys.flags;
|
||||
if (!input_pane_supports_extended(ictx->wp))
|
||||
n = 0;
|
||||
input_reply(ictx, 1, "\033[?%uu", n);
|
||||
input_reply(ictx, 1, "\033[?%uu", s->kitty_keys.flags);
|
||||
break;
|
||||
case INPUT_CSI_KITTY_SET:
|
||||
if (options_get_number(global_options, "extended-keys") == 0 ||
|
||||
options_get_number(global_options, "extended-keys-format") !=
|
||||
EXTENDED_KEYS_KITTY)
|
||||
if (options_get_number(global_options, "extended-keys") == 0)
|
||||
break;
|
||||
n = input_get(ictx, 0, 0, 0);
|
||||
m = input_get(ictx, 1, 1, 1);
|
||||
@@ -1616,18 +1579,14 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
input_kitty_set(s, n, m);
|
||||
break;
|
||||
case INPUT_CSI_KITTY_PUSH:
|
||||
if (options_get_number(global_options, "extended-keys") == 0 ||
|
||||
options_get_number(global_options, "extended-keys-format") !=
|
||||
EXTENDED_KEYS_KITTY)
|
||||
if (options_get_number(global_options, "extended-keys") == 0)
|
||||
break;
|
||||
n = input_get(ictx, 0, 0, 0);
|
||||
if (n >= 0)
|
||||
input_kitty_push(s, n);
|
||||
break;
|
||||
case INPUT_CSI_KITTY_POP:
|
||||
if (options_get_number(global_options, "extended-keys") == 0 ||
|
||||
options_get_number(global_options, "extended-keys-format") !=
|
||||
EXTENDED_KEYS_KITTY)
|
||||
if (options_get_number(global_options, "extended-keys") == 0)
|
||||
break;
|
||||
n = input_get(ictx, 0, 1, 1);
|
||||
if (n >= 0)
|
||||
|
||||
@@ -1400,6 +1400,12 @@ options_push_changes(const char *name)
|
||||
TAILQ_FOREACH(loop, &clients, entry)
|
||||
server_client_set_key_table(loop, NULL);
|
||||
}
|
||||
if (strcmp(name, "extended-keys") == 0) {
|
||||
TAILQ_FOREACH(loop, &clients, entry) {
|
||||
if (loop->tty.flags & TTY_STARTED)
|
||||
tty_update_features(&loop->tty);
|
||||
}
|
||||
}
|
||||
if (strcmp(name, "user-keys") == 0) {
|
||||
TAILQ_FOREACH(loop, &clients, entry) {
|
||||
if (loop->tty.flags & TTY_OPENED)
|
||||
|
||||
3
popup.c
3
popup.c
@@ -449,8 +449,7 @@ popup_key_cb(struct client *c, void *data, struct key_event *event)
|
||||
bufferevent_write(job_get_event(pd->job), buf, len);
|
||||
return (0);
|
||||
}
|
||||
input_key(&pd->s, job_get_event(pd->job), event->key,
|
||||
input_key_client_supports_extended(pd->c, event->key));
|
||||
input_key(&pd->s, job_get_event(pd->job), event->key);
|
||||
}
|
||||
return (0);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -437,9 +437,7 @@ screen_write_reset(struct screen_write_ctx *ctx)
|
||||
|
||||
s->mode = MODE_CURSOR|MODE_WRAP;
|
||||
|
||||
if (options_get_number(global_options, "extended-keys") == 2 &&
|
||||
options_get_number(global_options, "extended-keys-format") !=
|
||||
EXTENDED_KEYS_KITTY)
|
||||
if (options_get_number(global_options, "extended-keys") == 2)
|
||||
s->mode = (s->mode & ~EXTENDED_KEY_MODES)|MODE_KEYS_EXTENDED;
|
||||
input_kitty_reset(s);
|
||||
|
||||
|
||||
4
screen.c
4
screen.c
@@ -118,9 +118,7 @@ screen_reinit(struct screen *s, int check)
|
||||
|
||||
s->mode = MODE_CURSOR|MODE_WRAP|(s->mode & MODE_CRLF);
|
||||
|
||||
if (options_get_number(global_options, "extended-keys") == 2 &&
|
||||
options_get_number(global_options, "extended-keys-format") !=
|
||||
EXTENDED_KEYS_KITTY)
|
||||
if (options_get_number(global_options, "extended-keys") == 2)
|
||||
s->mode = (s->mode & ~EXTENDED_KEY_MODES)|MODE_KEYS_EXTENDED;
|
||||
if (SCREEN_IS_ALTERNATE(s))
|
||||
screen_alternate_off(s, NULL, 0);
|
||||
|
||||
79
tmux.1
79
tmux.1
@@ -4908,19 +4908,29 @@ If enabled, the server will exit when there are no attached clients.
|
||||
.Op Ic on | off | always
|
||||
.Xc
|
||||
Controls how modified keys are reported.
|
||||
For the
|
||||
.Ic csi\-u
|
||||
and
|
||||
.Ic xterm
|
||||
formats, this controls the
|
||||
When enabled,
|
||||
.Nm
|
||||
uses the Kitty keyboard protocol with terminals which support it, and the
|
||||
.Ic modifyOtherKeys
|
||||
.Xr xterm 1
|
||||
resource.
|
||||
For the
|
||||
.Ic kitty
|
||||
format, this controls the progressive keyboard protocol enhancements.
|
||||
resource with other terminals which support extended keys.
|
||||
Each client uses the best that its terminal supports, so clients with different
|
||||
terminals may be attached at the same time.
|
||||
.Pp
|
||||
When set to
|
||||
Programs inside panes may request either the Kitty keyboard protocol or
|
||||
.Ic modifyOtherKeys ,
|
||||
and keys are sent to each program in the form it requested, whichever client
|
||||
they were typed on.
|
||||
The Kitty keyboard protocol can report the Super and Hyper modifiers, whose key
|
||||
name prefixes are
|
||||
.Ql s-
|
||||
and
|
||||
.Ql H- ;
|
||||
its disambiguate and report-all enhancements are supported.
|
||||
.Pp
|
||||
For
|
||||
.Ic modifyOtherKeys ,
|
||||
when set to
|
||||
.Ic on ,
|
||||
the program inside the pane can request one of two modes: mode 1 which changes
|
||||
the sequence for only keys which lack an existing well-known representation; or
|
||||
@@ -4929,7 +4939,8 @@ When set to
|
||||
.Ic always ,
|
||||
modes 1 and 2 can still be requested by applications, but mode 1 will be forced
|
||||
instead of the standard mode.
|
||||
This applies only to applications inside panes and does not change what
|
||||
This applies only to applications inside panes; it does not force the Kitty
|
||||
keyboard protocol or change what
|
||||
.Nm
|
||||
requests from the terminal.
|
||||
When set to
|
||||
@@ -4938,19 +4949,12 @@ 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.
|
||||
A Kitty keyboard state query reflects the clients attached to the window at
|
||||
the time of the query; if none are attached, the requested state is reported.
|
||||
Applications are not notified if client support changes after the reply.
|
||||
Support for the Kitty keyboard protocol is detected when a client attaches.
|
||||
See also the
|
||||
.Ic kittykeys
|
||||
and
|
||||
.Ic extkeys
|
||||
feature for the
|
||||
features for the
|
||||
.Ic terminal\-features
|
||||
option, the
|
||||
.Ic extended\-keys\-format
|
||||
@@ -4962,22 +4966,9 @@ variables.
|
||||
.It Xo Ic extended\-keys\-format
|
||||
.Op Ic csi\-u | xterm | kitty
|
||||
.Xc
|
||||
Selects the format for reporting modified keys to applications.
|
||||
The
|
||||
.Ic kitty
|
||||
format uses the Kitty keyboard protocol and supports the Super and Hyper
|
||||
modifiers.
|
||||
Their key name prefixes are
|
||||
.Ql s-
|
||||
and
|
||||
.Ql H- .
|
||||
The disambiguate and report-all enhancements are supported; event types,
|
||||
alternate keys and associated text are not requested.
|
||||
For the
|
||||
.Ic csi\-u
|
||||
and
|
||||
.Ic xterm
|
||||
formats, this is the equivalent of the
|
||||
Selects the format for reporting modified keys to programs which request
|
||||
.Ic modifyOtherKeys .
|
||||
This is the equivalent of the
|
||||
.Ic formatOtherKeys
|
||||
.Xr xterm 1
|
||||
resource.
|
||||
@@ -4989,10 +4980,11 @@ and as
|
||||
.Ql \[ha][[65;6u
|
||||
when set to
|
||||
.Ic csi\-u .
|
||||
With
|
||||
.Ic kitty ,
|
||||
it will be reported as
|
||||
.Ql \[ha][[97;6u .
|
||||
.Ic kitty
|
||||
is accepted for compatibility and is the same as
|
||||
.Ic csi\-u ;
|
||||
programs which request the Kitty keyboard protocol receive it whatever this
|
||||
option is set to.
|
||||
.It Xo Ic focus\-events
|
||||
.Op Ic on | off
|
||||
.Xc
|
||||
@@ -5141,6 +5133,9 @@ Ignore function keys from
|
||||
and use the
|
||||
.Nm
|
||||
internal set only.
|
||||
.It kittykeys
|
||||
Supports the Kitty keyboard protocol.
|
||||
This is added automatically if the terminal answers the Kitty keyboard query.
|
||||
.It margins
|
||||
Supports DECSLRM margins.
|
||||
.It mouse
|
||||
|
||||
8
tmux.h
8
tmux.h
@@ -1829,6 +1829,7 @@ struct tty_term {
|
||||
#define TERM_VT100LIKE 0x20
|
||||
#define TERM_SIXEL 0x40
|
||||
#define TERM_INVALIDMS 0x80
|
||||
#define TERM_KITTYKEYS 0x100
|
||||
int flags;
|
||||
|
||||
LIST_ENTRY(tty_term) entry;
|
||||
@@ -1911,7 +1912,6 @@ struct tty {
|
||||
#define TTY_HAVESYNC 0x10000
|
||||
#define TTY_HAVEKKB 0x20000
|
||||
#define TTY_KKBPUSHED 0x40000
|
||||
#define TTY_KKBSUPPORT 0x80000
|
||||
#define TTY_ALL_REQUEST_FLAGS \
|
||||
(TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA|TTY_HAVESYNC|TTY_HAVEKKB)
|
||||
int flags;
|
||||
@@ -3545,12 +3545,10 @@ void input_cancel_requests(struct client *);
|
||||
|
||||
/* input-key.c */
|
||||
void input_key_build(void);
|
||||
int input_key_pane(struct window_pane *, key_code, struct mouse_event *,
|
||||
int);
|
||||
int input_key(struct screen *, struct bufferevent *, key_code, int);
|
||||
int input_key_pane(struct window_pane *, key_code, struct mouse_event *);
|
||||
int input_key(struct screen *, struct bufferevent *, key_code);
|
||||
int input_key_get_mouse(struct screen *, struct mouse_event *, u_int,
|
||||
u_int, const char **, size_t *);
|
||||
int input_key_client_supports_extended(struct client *, key_code);
|
||||
|
||||
/* input-kitty.c */
|
||||
void input_kitty_reset(struct screen *);
|
||||
|
||||
@@ -235,6 +235,13 @@ static const struct tty_feature tty_feature_sync = {
|
||||
0
|
||||
};
|
||||
|
||||
/* Terminal supports the Kitty keyboard protocol. */
|
||||
static const struct tty_feature tty_feature_kittykeys = {
|
||||
"kittykeys",
|
||||
NULL,
|
||||
TERM_KITTYKEYS
|
||||
};
|
||||
|
||||
/* Terminal supports extended keys. */
|
||||
static const char *const tty_feature_extkeys_capabilities[] = {
|
||||
"Eneks=\\E[>4;2m",
|
||||
@@ -386,6 +393,7 @@ static const struct tty_feature *const tty_features[] = {
|
||||
&tty_feature_extkeys,
|
||||
&tty_feature_focus,
|
||||
&tty_feature_ignorefkeys,
|
||||
&tty_feature_kittykeys,
|
||||
&tty_feature_margins,
|
||||
&tty_feature_mouse,
|
||||
&tty_feature_osc7,
|
||||
|
||||
18
tty-kitty.c
18
tty-kitty.c
@@ -261,10 +261,6 @@ tty_keys_kitty_query(struct tty *tty, const char *buf, size_t len,
|
||||
*size = 0;
|
||||
if (tty->flags & TTY_HAVEKKB)
|
||||
return (-1);
|
||||
if (options_get_number(global_options, "extended-keys") == 0 ||
|
||||
options_get_number(global_options, "extended-keys-format") !=
|
||||
EXTENDED_KEYS_KITTY)
|
||||
return (-1);
|
||||
|
||||
if (buf[0] != '\033')
|
||||
return (-1);
|
||||
@@ -291,8 +287,9 @@ tty_keys_kitty_query(struct tty *tty, const char *buf, size_t len,
|
||||
|
||||
*size = i + 1;
|
||||
tty->kitty_keys = flags;
|
||||
tty->flags |= (TTY_HAVEKKB|TTY_KKBSUPPORT);
|
||||
tty->flags |= TTY_HAVEKKB;
|
||||
log_debug("%s: received Kitty keyboard flags %u", c->name, flags);
|
||||
tty_parse_client_features(c, "kittykeys", ",");
|
||||
tty_update_features(tty);
|
||||
return (0);
|
||||
}
|
||||
@@ -304,18 +301,13 @@ tty_update_kitty(struct tty *tty, struct screen *s)
|
||||
char buf[32];
|
||||
|
||||
if (options_get_number(global_options, "extended-keys") == 0 ||
|
||||
options_get_number(global_options, "extended-keys-format") !=
|
||||
EXTENDED_KEYS_KITTY) {
|
||||
(~tty->term->flags & TERM_KITTYKEYS)) {
|
||||
if (tty->flags & TTY_KKBPUSHED) {
|
||||
tty_puts(tty, "\033[<u");
|
||||
tty->flags &= ~TTY_KKBPUSHED;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((tty->flags & (TTY_HAVEKKB|TTY_KKBSUPPORT)) !=
|
||||
(TTY_HAVEKKB|TTY_KKBSUPPORT))
|
||||
return;
|
||||
|
||||
flags = KITTY_KEY_DISAMBIGUATE;
|
||||
if (s != NULL && (s->kitty_keys.flags & KITTY_KEY_SUPPORTED) != 0)
|
||||
flags = s->kitty_keys.flags & KITTY_KEY_SUPPORTED;
|
||||
@@ -345,9 +337,7 @@ tty_keys_kitty(struct tty *tty, const char *buf, size_t len, size_t *size,
|
||||
int result;
|
||||
|
||||
*size = 0;
|
||||
if ((tty->flags & TTY_KKBPUSHED) == 0 ||
|
||||
options_get_number(global_options, "extended-keys-format") !=
|
||||
EXTENDED_KEYS_KITTY)
|
||||
if ((tty->flags & TTY_KKBPUSHED) == 0)
|
||||
return (-1);
|
||||
if (len == 0 || buf[0] != '\033')
|
||||
return (-1);
|
||||
|
||||
14
tty.c
14
tty.c
@@ -409,10 +409,7 @@ tty_send_requests(struct tty *tty)
|
||||
return;
|
||||
|
||||
if (tty->term->flags & TERM_VT100LIKE) {
|
||||
if (~tty->flags & TTY_HAVEKKB &&
|
||||
options_get_number(global_options, "extended-keys") != 0 &&
|
||||
options_get_number(global_options, "extended-keys-format") ==
|
||||
EXTENDED_KEYS_KITTY)
|
||||
if (~tty->flags & TTY_HAVEKKB)
|
||||
tty_puts(tty, "\033[?u");
|
||||
if (~tty->flags & TTY_HAVEDA)
|
||||
tty_puts(tty, "\033[c");
|
||||
@@ -562,19 +559,14 @@ 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);
|
||||
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)))
|
||||
if (options_get_number(global_options, "extended-keys") == 0 ||
|
||||
(tty->term->flags & TERM_KITTYKEYS))
|
||||
tty_puts(tty, tty_term_string(tty->term, TTYC_DSEKS));
|
||||
else
|
||||
tty_puts(tty, tty_term_string(tty->term, TTYC_ENEKS));
|
||||
|
||||
11
window.c
11
window.c
@@ -1980,8 +1980,7 @@ window_pane_copy_paste(struct window_pane *wp, char *buf, size_t len)
|
||||
}
|
||||
|
||||
static void
|
||||
window_pane_copy_key(struct window_pane *wp, key_code key,
|
||||
int extended_encoding)
|
||||
window_pane_copy_key(struct window_pane *wp, key_code key)
|
||||
{
|
||||
struct window_pane *loop;
|
||||
|
||||
@@ -1992,7 +1991,7 @@ window_pane_copy_key(struct window_pane *wp, key_code key,
|
||||
(~loop->flags & PANE_INPUTOFF) &&
|
||||
window_pane_is_visible(loop) &&
|
||||
options_get_number(loop->options, "synchronize-panes"))
|
||||
input_key_pane(loop, key, NULL, extended_encoding);
|
||||
input_key_pane(loop, key, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2020,7 +2019,6 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
|
||||
struct winlink *wl, key_code key, struct mouse_event *m)
|
||||
{
|
||||
struct window_mode_entry *wme;
|
||||
int extended_encoding;
|
||||
|
||||
if (KEYC_IS_MOUSE(key) && m == NULL)
|
||||
return (-1);
|
||||
@@ -2043,14 +2041,13 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
|
||||
if (wp->fd == -1 || wp->flags & PANE_INPUTOFF)
|
||||
return (0);
|
||||
|
||||
extended_encoding = input_key_client_supports_extended(c, key);
|
||||
if (input_key_pane(wp, key, m, extended_encoding) != 0)
|
||||
if (input_key_pane(wp, key, m) != 0)
|
||||
return (-1);
|
||||
|
||||
if (KEYC_IS_MOUSE(key))
|
||||
return (0);
|
||||
if (options_get_number(wp->options, "synchronize-panes"))
|
||||
window_pane_copy_key(wp, key, extended_encoding);
|
||||
window_pane_copy_key(wp, key);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user