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

51
input.c
View File

@@ -161,7 +161,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 *);
@@ -1178,29 +1177,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, ...)
@@ -1555,9 +1531,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;
@@ -1577,9 +1550,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;
@@ -1594,19 +1564,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);
@@ -1614,18 +1577,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)