From 0280c0e32a35bf0d1c08c54b8f0d91982c68f399 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 16 May 2020 16:44:55 +0000 Subject: Add a terminal feature for enable/disable extended keys (supported by xterm and mintty) and add an option to make tmux send it. Only forward extended keys if the application has requested them, even though we use the CSI u sequence and xterm uses CSI 27 ~ - this is what mintty does as well. --- usr.bin/tmux/input-keys.c | 68 +++++--------------------------------------- usr.bin/tmux/input.c | 21 ++++++++++++-- usr.bin/tmux/options-table.c | 10 ++++++- usr.bin/tmux/tmux.1 | 10 ++++++- usr.bin/tmux/tmux.h | 11 ++++--- usr.bin/tmux/tty-features.c | 19 +++++++++++-- usr.bin/tmux/tty-keys.c | 4 +-- usr.bin/tmux/tty-term.c | 4 ++- usr.bin/tmux/tty.c | 23 +++++++-------- 9 files changed, 83 insertions(+), 87 deletions(-) (limited to 'usr.bin') diff --git a/usr.bin/tmux/input-keys.c b/usr.bin/tmux/input-keys.c index 11b48768a7a..4936fa35b36 100644 --- a/usr.bin/tmux/input-keys.c +++ b/usr.bin/tmux/input-keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input-keys.c,v 1.75 2020/05/16 16:38:55 nicm Exp $ */ +/* $OpenBSD: input-keys.c,v 1.76 2020/05/16 16:44:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -497,67 +497,13 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key) } /* No builtin key sequence; construct an extended key sequence. */ - outkey = (key & KEYC_MASK_KEY); - if (outkey >= KEYC_BASE) { - switch (outkey) { - case KEYC_IC: - outkey = 2; - break; - case KEYC_DC: - outkey = 3; - break; - case KEYC_PPAGE: - outkey = 5; - break; - case KEYC_NPAGE: - outkey = 6; - break; - case KEYC_HOME: - outkey = 7; - break; - case KEYC_END: - outkey = 8; - break; - case KEYC_F1: - outkey = 11; - break; - case KEYC_F2: - outkey = 12; - break; - case KEYC_F3: - outkey = 13; - break; - case KEYC_F4: - outkey = 14; - break; - case KEYC_F5: - outkey = 15; - break; - case KEYC_F6: - outkey = 17; - break; - case KEYC_F7: - outkey = 18; - break; - case KEYC_F8: - outkey = 19; - break; - case KEYC_F9: - outkey = 20; - break; - case KEYC_F10: - outkey = 21; - break; - case KEYC_F11: - outkey = 23; - break; - case KEYC_F12: - outkey = 24; - break; - default: - goto missing; - } + if (~s->mode & MODE_KEXTENDED) { + if ((key & KEYC_MASK_MODIFIERS) == KEYC_CTRL && + (key & KEYC_MASK_KEY) < KEYC_BASE) + return (input_key(s, bev, key & ~KEYC_CTRL)); + goto missing; } + outkey = (key & KEYC_MASK_KEY); switch (key & KEYC_MASK_MODIFIERS) { case KEYC_SHIFT: modifier = '2'; diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c index 61023dbecd9..c1e9e0c650c 100644 --- a/usr.bin/tmux/input.c +++ b/usr.bin/tmux/input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input.c,v 1.177 2020/05/16 15:34:08 nicm Exp $ */ +/* $OpenBSD: input.c,v 1.178 2020/05/16 16:44:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -241,6 +241,8 @@ enum input_csi_type { INPUT_CSI_HPA, INPUT_CSI_ICH, INPUT_CSI_IL, + INPUT_CSI_MODOFF, + INPUT_CSI_MODSET, INPUT_CSI_RCP, INPUT_CSI_REP, INPUT_CSI_RM, @@ -289,7 +291,9 @@ static const struct input_table_entry input_csi_table[] = { { 'l', "", INPUT_CSI_RM }, { 'l', "?", INPUT_CSI_RM_PRIVATE }, { 'm', "", INPUT_CSI_SGR }, + { 'm', ">", INPUT_CSI_MODSET }, { 'n', "", INPUT_CSI_DSR }, + { 'n', ">", INPUT_CSI_MODOFF }, { 'q', " ", INPUT_CSI_DECSCUSR }, { 'q', ">", INPUT_CSI_XDA }, { 'r', "", INPUT_CSI_DECSTBM }, @@ -1380,6 +1384,19 @@ input_csi_dispatch(struct input_ctx *ictx) if (n != -1 && m != -1) screen_write_cursormove(sctx, m - 1, n - 1, 1); break; + case INPUT_CSI_MODSET: + n = input_get(ictx, 0, 0, 0); + m = input_get(ictx, 1, 0, 0); + if (n == 0 || (n == 4 && m == 0)) + screen_write_mode_clear(sctx, MODE_KEXTENDED); + else if (n == 4 && (m == 1 || m == 2)) + screen_write_mode_set(sctx, MODE_KEXTENDED); + break; + case INPUT_CSI_MODOFF: + n = input_get(ictx, 0, 0, 0); + if (n == 4) + screen_write_mode_clear(sctx, MODE_KEXTENDED); + break; case INPUT_CSI_WINOPS: input_csi_dispatch_winops(ictx); break; @@ -1593,7 +1610,7 @@ input_csi_dispatch(struct input_ctx *ictx) break; case INPUT_CSI_XDA: n = input_get(ictx, 0, 0, 0); - if (n != 0) + if (n == 0) input_reply(ictx, "\033P>|tmux %s\033\\", getversion()); break; diff --git a/usr.bin/tmux/options-table.c b/usr.bin/tmux/options-table.c index cfd4d304bb6..f414cb974f1 100644 --- a/usr.bin/tmux/options-table.c +++ b/usr.bin/tmux/options-table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options-table.c,v 1.130 2020/05/16 16:30:59 nicm Exp $ */ +/* $OpenBSD: options-table.c,v 1.131 2020/05/16 16:44:54 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott @@ -252,6 +252,14 @@ const struct options_table_entry options_table[] = { "clients." }, + { .name = "extended-keys", + .type = OPTIONS_TABLE_FLAG, + .scope = OPTIONS_TABLE_SERVER, + .default_num = 0, + .text = "Whether to request extended key sequences from terminals " + "that support it." + }, + { .name = "focus-events", .type = OPTIONS_TABLE_FLAG, .scope = OPTIONS_TABLE_SERVER, diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 972dec9dcef..14b58319ca5 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.771 2020/05/16 16:30:59 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.772 2020/05/16 16:44:54 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -3225,6 +3225,12 @@ sessions. .Op Ic on | off .Xc If enabled, the server will exit when there are no attached clients. +.It Xo Ic extended-keys +.Op Ic on | off +.Xc +When enabled, extended keys are requested from the terminal and if supported +are recognised by +.Nm . .It Xo Ic focus-events .Op Ic on | off .Xc @@ -5744,6 +5750,8 @@ Disable and enable bracketed paste. These are set automatically if the .Em XT capability is present. +.It Em \&Dseks , \&Eneks +Disable and enable extended keys. .It Em \&Dsfcs , \&Enfcs Disable and enable focus reporting. These are set automatically if the diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index de896a47d46..114c649f075 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1046 2020/05/16 16:35:13 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1047 2020/05/16 16:44:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -290,6 +290,7 @@ enum tty_code_code { TTYC_DL, TTYC_DL1, TTYC_DSBP, + TTYC_DSEKS, TTYC_DSFCS, TTYC_DSMG, TTYC_E3, @@ -299,6 +300,7 @@ enum tty_code_code { TTYC_EL1, TTYC_ENACS, TTYC_ENBP, + TTYC_ENEKS, TTYC_ENFCS, TTYC_ENMG, TTYC_FSL, @@ -575,8 +577,8 @@ struct msg_write_close { #define MODE_CURSOR 0x1 #define MODE_INSERT 0x2 #define MODE_KCURSOR 0x4 -#define MODE_KKEYPAD 0x8 /* set = application, clear = number */ -#define MODE_WRAP 0x10 /* whether lines wrap */ +#define MODE_KKEYPAD 0x8 +#define MODE_WRAP 0x10 #define MODE_MOUSE_STANDARD 0x20 #define MODE_MOUSE_BUTTON 0x40 #define MODE_BLINKING 0x80 @@ -587,6 +589,7 @@ struct msg_write_close { #define MODE_MOUSE_ALL 0x1000 #define MODE_ORIGIN 0x2000 #define MODE_CRLF 0x4000 +#define MODE_KEXTENDED 0x8000 #define ALL_MODES 0xffffff #define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL) @@ -1284,7 +1287,7 @@ struct tty { /* 0x8 unused */ #define TTY_STARTED 0x10 #define TTY_OPENED 0x20 -#define TTY_FOCUS 0x40 +/* 0x40 unused */ #define TTY_BLOCK 0x80 #define TTY_HAVEDA 0x100 #define TTY_HAVEXDA 0x200 diff --git a/usr.bin/tmux/tty-features.c b/usr.bin/tmux/tty-features.c index ab4d640c03d..efa3037fef4 100644 --- a/usr.bin/tmux/tty-features.c +++ b/usr.bin/tmux/tty-features.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-features.c,v 1.13 2020/05/16 14:46:14 nicm Exp $ */ +/* $OpenBSD: tty-features.c,v 1.14 2020/05/16 16:44:54 nicm Exp $ */ /* * Copyright (c) 2020 Nicholas Marriott @@ -190,6 +190,18 @@ static const struct tty_feature tty_feature_sync = { 0 }; +/* Terminal supports extended keys. */ +static const char *tty_feature_extkeys_capabilities[] = { + "Eneks=\\E[>4;1m", + "Dseks=\\E[>4m", + NULL +}; +static const struct tty_feature tty_feature_extkeys = { + "extkeys", + tty_feature_extkeys_capabilities, + 0 +}; + /* Terminal supports DECSLRM margins. */ static const char *tty_feature_margins_capabilities[] = { "Enmg=\\E[?69h", @@ -218,6 +230,7 @@ static const struct tty_feature *tty_features[] = { &tty_feature_ccolour, &tty_feature_clipboard, &tty_feature_cstyle, + &tty_feature_extkeys, &tty_feature_focus, &tty_feature_margins, &tty_feature_overline, @@ -321,7 +334,7 @@ tty_default_features(int *feat, const char *name, u_int version) } table[] = { #define TTY_FEATURES_BASE_MODERN_XTERM "256,RGB,bpaste,clipboard,strikethrough,title" { .name = "mintty", - .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,margins,overline" + .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,extkeys,margins,overline" }, { .name = "tmux", .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,focus,overline,usstyle" @@ -333,7 +346,7 @@ tty_default_features(int *feat, const char *name, u_int version) .features = TTY_FEATURES_BASE_MODERN_XTERM ",cstyle,margins,sync" }, { .name = "XTerm", - .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,focus,margins,rectfill" + .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,extkeys,focus,margins,rectfill" } }; u_int i; diff --git a/usr.bin/tmux/tty-keys.c b/usr.bin/tmux/tty-keys.c index beb94ed83ca..80b59c0d720 100644 --- a/usr.bin/tmux/tty-keys.c +++ b/usr.bin/tmux/tty-keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-keys.c,v 1.135 2020/05/16 16:35:13 nicm Exp $ */ +/* $OpenBSD: tty-keys.c,v 1.136 2020/05/16 16:44:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1293,7 +1293,7 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf, else if (strncmp(tmp, "tmux ", 5) == 0) tty_default_features(&c->term_features, "tmux", 0); else if (strncmp(tmp, "XTerm(", 6) == 0) - tty_default_features(&c->term_features, "xterm", 0); + tty_default_features(&c->term_features, "XTerm", 0); else if (strncmp(tmp, "mintty ", 7) == 0) tty_default_features(&c->term_features, "mintty", 0); log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf); diff --git a/usr.bin/tmux/tty-term.c b/usr.bin/tmux/tty-term.c index 2ca3c99123f..9fc710fc98a 100644 --- a/usr.bin/tmux/tty-term.c +++ b/usr.bin/tmux/tty-term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-term.c,v 1.80 2020/05/16 14:46:14 nicm Exp $ */ +/* $OpenBSD: tty-term.c,v 1.81 2020/05/16 16:44:54 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -83,6 +83,7 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_DIM] = { TTYCODE_STRING, "dim" }, [TTYC_DL1] = { TTYCODE_STRING, "dl1" }, [TTYC_DL] = { TTYCODE_STRING, "dl" }, + [TTYC_DSEKS] = { TTYCODE_STRING, "Dseks" }, [TTYC_DSFCS] = { TTYCODE_STRING, "Dsfcs" }, [TTYC_DSBP] = { TTYCODE_STRING, "Dsbp" }, [TTYC_DSMG] = { TTYCODE_STRING, "Dsmg" }, @@ -93,6 +94,7 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_EL] = { TTYCODE_STRING, "el" }, [TTYC_ENACS] = { TTYCODE_STRING, "enacs" }, [TTYC_ENBP] = { TTYCODE_STRING, "Enbp" }, + [TTYC_ENEKS] = { TTYCODE_STRING, "Eneks" }, [TTYC_ENFCS] = { TTYCODE_STRING, "Enfcs" }, [TTYC_ENMG] = { TTYCODE_STRING, "Enmg" }, [TTYC_FSL] = { TTYCODE_STRING, "fsl" }, diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c index 730bcc2d6b4..f5fe6374c46 100644 --- a/usr.bin/tmux/tty.c +++ b/usr.bin/tmux/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.377 2020/05/16 16:26:34 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.378 2020/05/16 16:44:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -286,6 +286,8 @@ tty_start_timer_callback(__unused int fd, __unused short events, void *data) struct client *c = tty->client; log_debug("%s: start timer fired", c->name); + if ((tty->flags & (TTY_HAVEDA|TTY_HAVEXDA)) == 0) + tty_update_features(tty); tty->flags |= (TTY_HAVEDA|TTY_HAVEXDA); } @@ -329,13 +331,6 @@ tty_start_tty(struct tty *tty) tty_puts(tty, "\033[?1006l\033[?1005l"); } - if (options_get_number(global_options, "focus-events")) { - tty->flags |= TTY_FOCUS; - tty_raw(tty, tty_term_string(tty->term, TTYC_ENFCS)); - } - if (tty->term->flags & TERM_VT100LIKE) - tty_puts(tty, "\033[?7727h"); - evtimer_set(&tty->start_timer, tty_start_timer_callback, tty); evtimer_add(&tty->start_timer, &tv); @@ -415,12 +410,10 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, "\033[?1006l\033[?1005l"); } - if (tty->flags & TTY_FOCUS) { - tty->flags &= ~TTY_FOCUS; - tty_raw(tty, tty_term_string(tty->term, TTYC_DSFCS)); - } if (tty->term->flags & TERM_VT100LIKE) tty_raw(tty, "\033[?7727l"); + tty_raw(tty, tty_term_string(tty->term, TTYC_DSFCS)); + tty_raw(tty, tty_term_string(tty->term, TTYC_DSEKS)); if (tty_use_margin(tty)) tty_raw(tty, tty_term_string(tty->term, TTYC_DSMG)); @@ -471,6 +464,12 @@ tty_update_features(struct tty *tty) if (tty_use_margin(tty)) tty_putcode(tty, TTYC_ENMG); + if (options_get_number(global_options, "extended-keys")) + tty_puts(tty, tty_term_string(tty->term, TTYC_ENEKS)); + if (options_get_number(global_options, "focus-events")) + tty_raw(tty, tty_term_string(tty->term, TTYC_ENFCS)); + if (tty->term->flags & TERM_VT100LIKE) + tty_puts(tty, "\033[?7727h"); } void -- cgit v1.2.3