From 0dd19442061ac92b6d9b61a91e4b262c2f08921f Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:10:29 +0000 Subject: Tweak the default choose modes formats: - Only show pane title if it is not default and not empty. - Add a prettier time format and use that instead of long ctime(). - Remove clutter and change the order. --- format.c | 129 +++++++++++++++++++++++++++++++++++++++++--------------- tmux.1 | 4 ++ window-buffer.c | 2 +- window-client.c | 3 +- window-tree.c | 8 ++-- 5 files changed, 106 insertions(+), 40 deletions(-) diff --git a/format.c b/format.c index f0a5a3b1..c43baf05 100644 --- a/format.c +++ b/format.c @@ -100,6 +100,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2) #define FORMAT_SESSIONS 0x80 #define FORMAT_WINDOWS 0x100 #define FORMAT_PANES 0x200 +#define FORMAT_PRETTY 0x400 /* Limit on recursion. */ #define FORMAT_LOOP_LIMIT 10 @@ -1322,6 +1323,52 @@ format_quote(const char *s) return (out); } +/* Make a prettier time. */ +static char * +format_pretty_time(time_t t) +{ + struct tm now_tm, tm; + time_t now, age; + char s[6]; + int m; + + time(&now); + if (now < t) + now = t; + age = now - t; + + localtime_r(&now, &now_tm); + localtime_r(&t, &tm); + + /* Last 24 hours. */ + if (age < 24 * 3600) { + strftime(s, sizeof s, "%H:%M", &tm); + return (xstrdup(s)); + } + + /* This month or last 28 days. */ + if ((tm.tm_year == now_tm.tm_year && tm.tm_mon == now_tm.tm_mon) || + age < 28 * 24 * 3600) { + strftime(s, sizeof s, "%a%d", &tm); + return (xstrdup(s)); + } + + /* Last 12 months. */ + if (now_tm.tm_mon == 0) + m = 11; + else + m = now_tm.tm_mon - 1; + if ((tm.tm_year == now_tm.tm_year && tm.tm_mon < now_tm.tm_mon) || + (tm.tm_year == now_tm.tm_year - 1 && tm.tm_mon > now_tm.tm_mon)) { + strftime(s, sizeof s, "%d%b", &tm); + return (xstrdup(s)); + } + + /* Older than that. */ + strftime(s, sizeof s, "%h%y", &tm); + return (xstrdup(s)); +} + /* Find a format entry. */ static char * format_find(struct format_tree *ft, const char *key, int modifiers) @@ -1331,40 +1378,31 @@ format_find(struct format_tree *ft, const char *key, int modifiers) static char s[64]; struct options_entry *o; int idx; - char *found, *saved; - - if (~modifiers & FORMAT_TIMESTRING) { - o = options_parse_get(global_options, key, &idx, 0); - if (o == NULL && ft->wp != NULL) - o = options_parse_get(ft->wp->options, key, &idx, 0); - if (o == NULL && ft->w != NULL) - o = options_parse_get(ft->w->options, key, &idx, 0); - if (o == NULL) - o = options_parse_get(global_w_options, key, &idx, 0); - if (o == NULL && ft->s != NULL) - o = options_parse_get(ft->s->options, key, &idx, 0); - if (o == NULL) - o = options_parse_get(global_s_options, key, &idx, 0); - if (o != NULL) { - found = options_tostring(o, idx, 1); - goto found; - } + char *found = NULL, *saved; + const char *errstr; + time_t t = 0; + + o = options_parse_get(global_options, key, &idx, 0); + if (o == NULL && ft->wp != NULL) + o = options_parse_get(ft->wp->options, key, &idx, 0); + if (o == NULL && ft->w != NULL) + o = options_parse_get(ft->w->options, key, &idx, 0); + if (o == NULL) + o = options_parse_get(global_w_options, key, &idx, 0); + if (o == NULL && ft->s != NULL) + o = options_parse_get(ft->s->options, key, &idx, 0); + if (o == NULL) + o = options_parse_get(global_s_options, key, &idx, 0); + if (o != NULL) { + found = options_tostring(o, idx, 1); + goto found; } - found = NULL; - fe_find.key = (char *) key; + fe_find.key = (char *)key; fe = RB_FIND(format_entry_tree, &ft->tree, &fe_find); if (fe != NULL) { - if (modifiers & FORMAT_TIMESTRING) { - if (fe->t == 0) - return (NULL); - ctime_r(&fe->t, s); - s[strcspn(s, "\n")] = '\0'; - found = xstrdup(s); - goto found; - } if (fe->t != 0) { - xasprintf(&found, "%lld", (long long)fe->t); + t = fe->t; goto found; } if (fe->value == NULL && fe->cb != NULL) @@ -1390,7 +1428,28 @@ format_find(struct format_tree *ft, const char *key, int modifiers) return (NULL); found: - if (found == NULL) + if (modifiers & FORMAT_TIMESTRING) { + if (t == 0 && found != NULL) { + t = strtonum(found, 0, INT64_MAX, &errstr); + if (errstr != NULL) + t = 0; + free(found); + } + if (t == 0) + return (NULL); + if (modifiers & FORMAT_PRETTY) + found = format_pretty_time(t); + else { + ctime_r(&t, s); + s[strcspn(s, "\n")] = '\0'; + found = xstrdup(s); + } + return (found); + } + + if (t != 0) + xasprintf(&found, "%lld", (long long)t); + else if (found == NULL) return (NULL); if (modifiers & FORMAT_BASENAME) { saved = found; @@ -1532,7 +1591,7 @@ format_build_modifiers(struct format_tree *ft, const char **s, u_int *count) cp++; /* Check single character modifiers with no arguments. */ - if (strchr("lbdtqETSWP<>", cp[0]) != NULL && + if (strchr("lbdqETSWP<>", cp[0]) != NULL && format_is_end(cp[1])) { format_add_modifier(&list, count, cp, 1, NULL, 0); cp++; @@ -1553,7 +1612,7 @@ format_build_modifiers(struct format_tree *ft, const char **s, u_int *count) } /* Now try single character with arguments. */ - if (strchr("mCs=pe", cp[0]) == NULL) + if (strchr("mCst=pe", cp[0]) == NULL) break; c = cp[0]; @@ -1978,7 +2037,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, case 'e': if (fm->argc < 1 || fm->argc > 3) break; - mexp = fm; + mexp = fm; break; case 'l': modifiers |= FORMAT_LITERAL; @@ -1991,6 +2050,10 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, break; case 't': modifiers |= FORMAT_TIMESTRING; + if (fm->argc < 1) + break; + if (strchr(fm->argv[0], 'p') != NULL) + modifiers |= FORMAT_PRETTY; break; case 'q': modifiers |= FORMAT_QUOTE; diff --git a/tmux.1 b/tmux.1 index d1c44216..71876d83 100644 --- a/tmux.1 +++ b/tmux.1 @@ -4353,6 +4353,10 @@ gives .Ql #{t:window_activity} gives .Ql Sun Oct 25 09:25:02 2015 . +Adding +.Ql p ( +.Ql `t/p` ) +will use shorter but less accurate time format for times in the past. The .Ql b:\& and diff --git a/window-buffer.c b/window-buffer.c index 37707233..dae8899e 100644 --- a/window-buffer.c +++ b/window-buffer.c @@ -37,7 +37,7 @@ static void window_buffer_key(struct window_mode_entry *, #define WINDOW_BUFFER_DEFAULT_COMMAND "paste-buffer -b '%%'" #define WINDOW_BUFFER_DEFAULT_FORMAT \ - "#{buffer_size} bytes (#{t:buffer_created})" + "#{t/p:buffer_created}: #{buffer_sample}" static const struct menu_item window_buffer_menu_items[] = { { "Paste", 'p', NULL }, diff --git a/window-client.c b/window-client.c index 4688cbf3..cd424dd7 100644 --- a/window-client.c +++ b/window-client.c @@ -37,8 +37,7 @@ static void window_client_key(struct window_mode_entry *, #define WINDOW_CLIENT_DEFAULT_COMMAND "detach-client -t '%%'" #define WINDOW_CLIENT_DEFAULT_FORMAT \ - "session #{session_name} " \ - "(#{client_width}x#{client_height}, #{t:client_activity})" + "#{t/p:client_activity}: session #{session_name}" static const struct menu_item window_client_menu_items[] = { { "Detach", 'd', NULL }, diff --git a/window-tree.c b/window-tree.c index 156aafd9..2eff4b8a 100644 --- a/window-tree.c +++ b/window-tree.c @@ -38,13 +38,13 @@ static void window_tree_key(struct window_mode_entry *, #define WINDOW_TREE_DEFAULT_FORMAT \ "#{?pane_format," \ "#{?pane_marked,#[reverse],}" \ - "#{pane_current_command}#{?pane_active,*,}#{?pane_marked,M,} \"#{pane_title}\"" \ + "#{pane_current_command}#{?pane_active,*,}#{?pane_marked,M,}" \ + "#{?#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}},: \"#{pane_title}\",}" \ "," \ "#{?window_format," \ "#{?window_marked_flag,#[reverse],}" \ - "#{window_name}#{window_flags} " \ - "(#{window_panes} panes)" \ - "#{?#{==:#{window_panes},1}, \"#{pane_title}\",}" \ + "#{window_name}#{window_flags}" \ + "#{?#{&&:#{==:#{window_panes},1},#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}}},: \"#{pane_title}\",}" \ "," \ "#{session_windows} windows" \ "#{?session_grouped, " \ -- cgit From 471f697423df33d535a7cc1fac5f01f718969e34 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:13:37 +0000 Subject: Add an attribute for ACS. --- attributes.c | 4 +++- style.c | 4 ++-- tmux.1 | 5 ++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/attributes.c b/attributes.c index ca88a056..b839f06d 100644 --- a/attributes.c +++ b/attributes.c @@ -31,7 +31,8 @@ attributes_tostring(int attr) if (attr == 0) return ("none"); - len = xsnprintf(buf, sizeof buf, "%s%s%s%s%s%s%s%s%s%s%s%s%s", + len = xsnprintf(buf, sizeof buf, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + (attr & GRID_ATTR_CHARSET) ? "acs," : "", (attr & GRID_ATTR_BRIGHT) ? "bright," : "", (attr & GRID_ATTR_DIM) ? "dim," : "", (attr & GRID_ATTR_UNDERSCORE) ? "underscore," : "", @@ -62,6 +63,7 @@ attributes_fromstring(const char *str) const char *name; int attr; } table[] = { + { "acs", GRID_ATTR_CHARSET }, { "bright", GRID_ATTR_BRIGHT }, { "bold", GRID_ATTR_BRIGHT }, { "dim", GRID_ATTR_DIM }, diff --git a/style.c b/style.c index 6ba4c524..da3b4c78 100644 --- a/style.c +++ b/style.c @@ -26,7 +26,7 @@ #include "tmux.h" /* Mask for bits not included in style. */ -#define STYLE_ATTR_MASK (~GRID_ATTR_CHARSET) +#define STYLE_ATTR_MASK (~0) /* Default style. */ static struct style style_default = { @@ -247,7 +247,7 @@ style_tostring(struct style *sy) colour_tostring(gc->bg)); comma = ","; } - if (gc->attr != 0 && gc->attr != GRID_ATTR_CHARSET) { + if (gc->attr != 0) { xsnprintf(s + off, sizeof s - off, "%s%s", comma, attributes_tostring(gc->attr)); comma = ","; diff --git a/tmux.1 b/tmux.1 index 71876d83..a519b6b5 100644 --- a/tmux.1 +++ b/tmux.1 @@ -4661,7 +4661,8 @@ for the terminal default colour; or a hexadecimal RGB string such as Set the background colour. .It Ic none Set no attributes (turn off any active attributes). -.It Xo Ic bright +.It Xo Ic acs , +.Ic bright (or .Ic bold ) , .Ic dim , @@ -4681,6 +4682,8 @@ Set an attribute. Any of the attributes may be prefixed with .Ql no to unset. +.Ic acs +is the terminal alternate character set. .It Xo Ic align=left (or .Ic noalign ) , -- cgit From 9dd58470e41bfb5b9d74028eed73f502e71152f0 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:16:25 +0000 Subject: Remove support for iTerm2's DSR 1337 extension and use the CSI > q extension now supported by a few different terminals. --- input.c | 16 ++++++++-------- tmux.h | 2 +- tty-features.c | 2 +- tty-keys.c | 54 +++++++++++++++++++++++++++++++----------------------- tty.c | 8 ++++---- 5 files changed, 45 insertions(+), 37 deletions(-) diff --git a/input.c b/input.c index 919cf15d..b62b1858 100644 --- a/input.c +++ b/input.c @@ -254,6 +254,7 @@ enum input_csi_type { INPUT_CSI_TBC, INPUT_CSI_VPA, INPUT_CSI_WINOPS, + INPUT_CSI_XDA, }; /* Control (CSI) command table. */ @@ -290,6 +291,7 @@ static const struct input_table_entry input_csi_table[] = { { 'm', "", INPUT_CSI_SGR }, { 'n', "", INPUT_CSI_DSR }, { 'q', " ", INPUT_CSI_DECSCUSR }, + { 'q', ">", INPUT_CSI_XDA }, { 'r', "", INPUT_CSI_DECSTBM }, { 's', "", INPUT_CSI_SCP }, { 't', "", INPUT_CSI_WINOPS }, @@ -1324,7 +1326,6 @@ input_csi_dispatch(struct input_ctx *ictx) struct input_table_entry *entry; int i, n, m; u_int cx, bg = ictx->cell.cell.bg; - char *copy, *cp; if (ictx->flags & INPUT_DISCARD) return (0); @@ -1456,13 +1457,6 @@ input_csi_dispatch(struct input_ctx *ictx) case 6: input_reply(ictx, "\033[%u;%uR", s->cy + 1, s->cx + 1); break; - case 1337: /* Terminal version, from iTerm2. */ - copy = xstrdup(getversion()); - for (cp = copy; *cp != '\0'; cp++) - *cp = toupper((u_char)*cp); - input_reply(ictx, "\033[TMUX %sn", copy); - free(copy); - break; default: log_debug("%s: unknown '%c'", __func__, ictx->ch); break; @@ -1597,6 +1591,12 @@ input_csi_dispatch(struct input_ctx *ictx) if (n != -1) screen_set_cursor_style(s, n); break; + case INPUT_CSI_XDA: + n = input_get(ictx, 0, 0, 0); + if (n != 0) + input_reply(ictx, "\033P>|tmux %s\033\\", getversion()); + break; + } ictx->last = -1; diff --git a/tmux.h b/tmux.h index 67dc8631..c58be54f 100644 --- a/tmux.h +++ b/tmux.h @@ -1247,7 +1247,7 @@ struct tty { #define TTY_FOCUS 0x40 #define TTY_BLOCK 0x80 #define TTY_HAVEDA 0x100 -#define TTY_HAVEDSR 0x200 +#define TTY_HAVEXDA 0x200 #define TTY_SYNCING 0x400 int flags; diff --git a/tty-features.c b/tty-features.c index 1996c750..a7f2a4b0 100644 --- a/tty-features.c +++ b/tty-features.c @@ -33,7 +33,7 @@ * - alternate escape (under XT). * * Also: - * - XT is used to decide whether to send DA and DSR; + * - XT is used to decide whether to send DA and XDA; * - DECSLRM and DECFRA use a flag instead of capabilities; * - UTF-8 is a separate flag on the client; needed for unattached clients. */ diff --git a/tty-keys.c b/tty-keys.c index aa775d69..9e8428f2 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -52,7 +52,7 @@ static int tty_keys_clipboard(struct tty *, const char *, size_t, size_t *); static int tty_keys_device_attributes(struct tty *, const char *, size_t, size_t *); -static int tty_keys_device_status_report(struct tty *, const char *, +static int tty_keys_extended_device_attributes(struct tty *, const char *, size_t, size_t *); /* Default raw keys. */ @@ -612,8 +612,8 @@ tty_keys_next(struct tty *tty) goto partial_key; } - /* Is this a device status report response? */ - switch (tty_keys_device_status_report(tty, buf, len, &size)) { + /* Is this an extended device attributes response? */ + switch (tty_keys_extended_device_attributes(tty, buf, len, &size)) { case 0: /* yes */ key = KEYC_UNKNOWN; goto complete_key; @@ -936,7 +936,7 @@ tty_keys_clipboard(__unused struct tty *tty, const char *buf, size_t len, *size = 0; - /* First three bytes are always \033]52;. */ + /* First five bytes are always \033]52;. */ if (buf[0] != '\033') return (-1); if (len == 1) @@ -1040,9 +1040,11 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len, return (1); /* Copy the rest up to a 'c'. */ - for (i = 0; i < (sizeof tmp) - 1 && buf[3 + i] != 'c'; i++) { + for (i = 0; i < (sizeof tmp) - 1; i++) { if (3 + i == len) return (1); + if (buf[3 + i] == 'c') + break; tmp[i] = buf[3 + i]; } if (i == (sizeof tmp) - 1) @@ -1101,48 +1103,54 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len, } /* - * Handle device status report input. Returns 0 for success, -1 for failure, 1 - * for partial. + * Handle extended device attributes input. Returns 0 for success, -1 for + * failure, 1 for partial. */ static int -tty_keys_device_status_report(struct tty *tty, const char *buf, size_t len, - size_t *size) +tty_keys_extended_device_attributes(struct tty *tty, const char *buf, + size_t len, size_t *size) { struct client *c = tty->client; u_int i; char tmp[64]; *size = 0; - if (tty->flags & TTY_HAVEDSR) + if (tty->flags & TTY_HAVEXDA) return (-1); - /* First three bytes are always \033[. */ + /* First four bytes are always \033P>|. */ if (buf[0] != '\033') return (-1); if (len == 1) return (1); - if (buf[1] != '[') + if (buf[1] != 'P') return (-1); if (len == 2) return (1); - if (buf[2] != 'I' && buf[2] != 'T') + if (buf[2] != '>') return (-1); if (len == 3) return (1); + if (buf[3] != '|') + return (-1); + if (len == 4) + return (1); - /* Copy the rest up to a 'n'. */ - for (i = 0; i < (sizeof tmp) - 1 && buf[2 + i] != 'n'; i++) { - if (2 + i == len) + /* Copy the rest up to a '\033\\'. */ + for (i = 0; i < (sizeof tmp) - 1; i++) { + if (4 + i == len) return (1); - tmp[i] = buf[2 + i]; + if (buf[4 + i - 1] == '\033' && buf[4 + i] == '\\') + break; + tmp[i] = buf[4 + i]; } if (i == (sizeof tmp) - 1) return (-1); - tmp[i] = '\0'; - *size = 3 + i; + tmp[i - 1] = '\0'; + *size = 5 + i; /* Add terminal features. */ - if (strncmp(tmp, "ITERM2 ", 7) == 0) { + if (strncmp(tmp, "ITerm2 ", 7) == 0) { tty_add_features(&c->term_features, "256," "RGB," @@ -1152,7 +1160,7 @@ tty_keys_device_status_report(struct tty *tty, const char *buf, size_t len, "sync," "title", ","); - } else if (strncmp(tmp, "TMUX ", 5) == 0) { + } else if (strncmp(tmp, "tmux ", 5) == 0) { tty_add_features(&c->term_features, "256," "RGB," @@ -1163,10 +1171,10 @@ tty_keys_device_status_report(struct tty *tty, const char *buf, size_t len, "usstyle", ","); } - log_debug("%s: received DSR %.*s", c->name, (int)*size, buf); + log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf); tty_update_features(tty); - tty->flags |= TTY_HAVEDSR; + tty->flags |= TTY_HAVEXDA; return (0); } diff --git a/tty.c b/tty.c index 98a557b5..5d7d2c0d 100644 --- a/tty.c +++ b/tty.c @@ -287,7 +287,7 @@ 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); - tty->flags |= (TTY_HAVEDA|TTY_HAVEDSR); + tty->flags |= (TTY_HAVEDA|TTY_HAVEXDA); } void @@ -361,10 +361,10 @@ tty_send_requests(struct tty *tty) if (tty_term_flag(tty->term, TTYC_XT)) { if (~tty->flags & TTY_HAVEDA) tty_puts(tty, "\033[>c"); - if (~tty->flags & TTY_HAVEDSR) - tty_puts(tty, "\033[1337n"); + if (~tty->flags & TTY_HAVEXDA) + tty_puts(tty, "\033[>q"); } else - tty->flags |= (TTY_HAVEDA|TTY_HAVEDSR); + tty->flags |= (TTY_HAVEDA|TTY_HAVEXDA); } void -- cgit From 41dec585df8723a8e268a80930d7f9ce395829dc Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:18:39 +0000 Subject: Response is iTerm2 not not ITerm2. --- tty-keys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tty-keys.c b/tty-keys.c index 9e8428f2..8c778b2a 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -1150,7 +1150,7 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf, *size = 5 + i; /* Add terminal features. */ - if (strncmp(tmp, "ITerm2 ", 7) == 0) { + if (strncmp(tmp, "iTerm2 ", 7) == 0) { tty_add_features(&c->term_features, "256," "RGB," -- cgit From 4e0a718666e3c24e69be107d0a294a9ae9f59388 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:22:51 +0000 Subject: Add extension terminfo(5) capabilities for margins. --- tmux.1 | 2 ++ tmux.h | 10 +++++++--- tty-features.c | 15 ++++++++++++--- tty-term.c | 8 ++++++-- tty.c | 13 +++++-------- window-copy.c | 1 + 6 files changed, 33 insertions(+), 16 deletions(-) diff --git a/tmux.1 b/tmux.1 index a519b6b5..daa0739c 100644 --- a/tmux.1 +++ b/tmux.1 @@ -5565,6 +5565,8 @@ to change the cursor colour from inside .Bd -literal -offset indent $ printf '\e033]12;red\e033\e\e' .Ed +.It Em \&Cmg, \&Clmg, \&Dsmg , \&Enmg +Set, clear, disable or enable DECSLRM margins. .It Em \&Smol Enable the overline attribute. .It Em \&Smulx diff --git a/tmux.h b/tmux.h index c58be54f..97024310 100644 --- a/tmux.h +++ b/tmux.h @@ -254,6 +254,8 @@ enum tty_code_code { TTYC_BOLD, TTYC_CIVIS, TTYC_CLEAR, + TTYC_CLMG, + TTYC_CMG, TTYC_CNORM, TTYC_COLORS, TTYC_CR, @@ -274,12 +276,14 @@ enum tty_code_code { TTYC_DIM, TTYC_DL, TTYC_DL1, + TTYC_DSMG, TTYC_E3, TTYC_ECH, TTYC_ED, TTYC_EL, TTYC_EL1, TTYC_ENACS, + TTYC_ENMG, TTYC_FSL, TTYC_HOME, TTYC_HPA, @@ -445,11 +449,11 @@ enum tty_code_code { TTYC_SITM, TTYC_SMACS, TTYC_SMCUP, - TTYC_SMOL, TTYC_SMKX, + TTYC_SMOL, TTYC_SMSO, - TTYC_SMULX, TTYC_SMUL, + TTYC_SMULX, TTYC_SMXX, TTYC_SS, TTYC_SYNC, @@ -458,7 +462,7 @@ enum tty_code_code { TTYC_U8, TTYC_VPA, TTYC_XENL, - TTYC_XT, + TTYC_XT }; /* Message codes. */ diff --git a/tty-features.c b/tty-features.c index a7f2a4b0..9eb446d4 100644 --- a/tty-features.c +++ b/tty-features.c @@ -34,7 +34,7 @@ * * Also: * - XT is used to decide whether to send DA and XDA; - * - DECSLRM and DECFRA use a flag instead of capabilities; + * - DECFRA uses a flag instead of capabilities; * - UTF-8 is a separate flag on the client; needed for unattached clients. */ @@ -84,7 +84,7 @@ static const char *tty_feature_rgb_capabilities[] = { static struct tty_feature tty_feature_rgb = { "RGB", tty_feature_rgb_capabilities, - (TERM_256COLOURS|TERM_RGBCOLOURS) + TERM_256COLOURS|TERM_RGBCOLOURS }; /* Terminal supports 256 colours. */ @@ -159,9 +159,16 @@ static struct tty_feature tty_feature_sync = { }; /* Terminal supports DECSLRM margins. */ +static const char *tty_feature_margins_capabilities[] = { + "Enmg=\\E[?69h", + "Dsmg=\\E[?69l", + "Clmg=\\E[s", + "Cmg=\\E[%i%p1%d;%p2%ds", + NULL +}; static struct tty_feature tty_feature_margins = { "margins", - NULL, + tty_feature_margins_capabilities, TERM_DECSLRM }; @@ -194,6 +201,8 @@ tty_add_features(int *feat, const char *s, const char *separators) char *next, *loop, *copy; u_int i; + log_debug("%s: %s", __func__, s); + loop = copy = xstrdup(s); while ((next = strsep(&loop, separators)) != NULL) { for (i = 0; i < nitems(tty_features); i++) { diff --git a/tty-term.c b/tty-term.c index f3dbae5c..78ba5a37 100644 --- a/tty-term.c +++ b/tty-term.c @@ -61,6 +61,8 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_BOLD] = { TTYCODE_STRING, "bold" }, [TTYC_CIVIS] = { TTYCODE_STRING, "civis" }, [TTYC_CLEAR] = { TTYCODE_STRING, "clear" }, + [TTYC_CLMG] = { TTYCODE_STRING, "Clmg" }, + [TTYC_CMG] = { TTYCODE_STRING, "Cmg" }, [TTYC_CNORM] = { TTYCODE_STRING, "cnorm" }, [TTYC_COLORS] = { TTYCODE_NUMBER, "colors" }, [TTYC_CR] = { TTYCODE_STRING, "Cr" }, @@ -81,12 +83,14 @@ 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_DSMG] = { TTYCODE_STRING, "Dsmg" }, [TTYC_E3] = { TTYCODE_STRING, "E3" }, [TTYC_ECH] = { TTYCODE_STRING, "ech" }, [TTYC_ED] = { TTYCODE_STRING, "ed" }, [TTYC_EL1] = { TTYCODE_STRING, "el1" }, [TTYC_EL] = { TTYCODE_STRING, "el" }, [TTYC_ENACS] = { TTYCODE_STRING, "enacs" }, + [TTYC_ENMG] = { TTYCODE_STRING, "Enmg" }, [TTYC_FSL] = { TTYCODE_STRING, "fsl" }, [TTYC_HOME] = { TTYCODE_STRING, "home" }, [TTYC_HPA] = { TTYCODE_STRING, "hpa" }, @@ -237,8 +241,8 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_OP] = { TTYCODE_STRING, "op" }, [TTYC_REV] = { TTYCODE_STRING, "rev" }, [TTYC_RGB] = { TTYCODE_FLAG, "RGB" }, - [TTYC_RI] = { TTYCODE_STRING, "ri" }, [TTYC_RIN] = { TTYCODE_STRING, "rin" }, + [TTYC_RI] = { TTYCODE_STRING, "ri" }, [TTYC_RMACS] = { TTYCODE_STRING, "rmacs" }, [TTYC_RMCUP] = { TTYCODE_STRING, "rmcup" }, [TTYC_RMKX] = { TTYCODE_STRING, "rmkx" }, @@ -265,7 +269,7 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_U8] = { TTYCODE_NUMBER, "U8" }, [TTYC_VPA] = { TTYCODE_STRING, "vpa" }, [TTYC_XENL] = { TTYCODE_FLAG, "xenl" }, - [TTYC_XT] = { TTYCODE_FLAG, "XT" }, + [TTYC_XT] = { TTYCODE_FLAG, "XT" } }; u_int diff --git a/tty.c b/tty.c index 5d7d2c0d..5d84c9e8 100644 --- a/tty.c +++ b/tty.c @@ -426,7 +426,7 @@ tty_stop_tty(struct tty *tty) } if (tty_use_margin(tty)) - tty_raw(tty, "\033[?69l"); /* DECLRMM */ + tty_raw(tty, tty_term_string(tty->term, TTYC_DSMG)); tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); setblocking(tty->fd, 1); @@ -473,7 +473,7 @@ tty_update_features(struct tty *tty) tty_term_apply_overrides(tty->term); if (tty_use_margin(tty)) - tty_puts(tty, "\033[?69h"); /* DECLRMM */ + tty_putcode(tty, TTYC_ENMG); } void @@ -2028,7 +2028,7 @@ tty_invalidate(struct tty *tty) if (tty->flags & TTY_STARTED) { if (tty_use_margin(tty)) - tty_puts(tty, "\033[?69h"); /* DECLRMM */ + tty_putcode(tty, TTYC_ENMG); tty_putcode(tty, TTYC_SGR0); tty->mode = ALL_MODES; @@ -2105,8 +2105,6 @@ tty_margin_pane(struct tty *tty, const struct tty_ctx *ctx) static void tty_margin(struct tty *tty, u_int rleft, u_int rright) { - char s[64]; - if (!tty_use_margin(tty)) return; if (tty->rleft == rleft && tty->rright == rright) @@ -2118,10 +2116,9 @@ tty_margin(struct tty *tty, u_int rleft, u_int rright) tty->rright = rright; if (rleft == 0 && rright == tty->sx - 1) - snprintf(s, sizeof s, "\033[s"); + tty_putcode(tty, TTYC_CLMG); else - snprintf(s, sizeof s, "\033[%u;%us", rleft + 1, rright + 1); - tty_puts(tty, s); + tty_putcode2(tty, TTYC_CMG, rleft, rright); tty->cx = tty->cy = UINT_MAX; } diff --git a/window-copy.c b/window-copy.c index 2bda5d56..a803f3b3 100644 --- a/window-copy.c +++ b/window-copy.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "tmux.h" -- cgit From a29196ca6a6401053d3a17d0ffe2d560918683a4 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:26:33 +0000 Subject: Build list of paths and weed out duplicates before loading configs, and add TMUX_SOCK like TMUX_PATH for the socket directory. --- cfg.c | 55 +++++------------------------ tmux.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++---------- tmux.h | 7 +++- tty-features.c | 2 +- 4 files changed, 105 insertions(+), 67 deletions(-) diff --git a/cfg.c b/cfg.c index f67a765c..7c01f614 100644 --- a/cfg.c +++ b/cfg.c @@ -67,45 +67,12 @@ set_cfg_file(const char *path) cfg_file = xstrdup(path); } -static char * -expand_cfg_file(const char *path, const char *home) -{ - char *expanded, *name; - const char *end; - struct environ_entry *value; - - if (strncmp(path, "~/", 2) == 0) { - if (home == NULL) - return (NULL); - xasprintf(&expanded, "%s%s", home, path + 1); - return (expanded); - } - - if (*path == '$') { - end = strchr(path, '/'); - if (end == NULL) - name = xstrdup(path + 1); - else - name = xstrndup(path + 1, end - path - 1); - value = environ_find(global_environ, name); - free(name); - if (value == NULL) - return (NULL); - if (end == NULL) - end = ""; - xasprintf(&expanded, "%s%s", value->value, end); - return (expanded); - } - - return (xstrdup(path)); -} - void start_cfg(void) { - const char *home = find_home(); - struct client *c; - char *path, *copy, *next, *expanded; + struct client *c; + char **paths; + u_int i, n; /* * Configuration files are loaded without a client, so commands are run @@ -124,18 +91,12 @@ start_cfg(void) } if (cfg_file == NULL) { - path = copy = xstrdup(TMUX_CONF); - while ((next = strsep(&path, ":")) != NULL) { - expanded = expand_cfg_file(next, home); - if (expanded == NULL) { - log_debug("couldn't expand %s", next); - continue; - } - log_debug("expanded %s to %s", next, expanded); - load_cfg(expanded, c, NULL, CMD_PARSE_QUIET, NULL); - free(expanded); + expand_paths(TMUX_CONF, &paths, &n); + for (i = 0; i < n; i++) { + load_cfg(paths[i], c, NULL, CMD_PARSE_QUIET, NULL); + free(paths[i]); } - free(copy); + free(paths); } else load_cfg(cfg_file, c, NULL, 0, NULL); diff --git a/tmux.c b/tmux.c index 515f1543..db86dc52 100644 --- a/tmux.c +++ b/tmux.c @@ -109,34 +109,104 @@ areshell(const char *shell) return (0); } +static char * +expand_path(const char *path, const char *home) +{ + char *expanded, *name; + const char *end; + struct environ_entry *value; + + if (strncmp(path, "~/", 2) == 0) { + if (home == NULL) + return (NULL); + xasprintf(&expanded, "%s%s", home, path + 1); + return (expanded); + } + + if (*path == '$') { + end = strchr(path, '/'); + if (end == NULL) + name = xstrdup(path + 1); + else + name = xstrndup(path + 1, end - path - 1); + value = environ_find(global_environ, name); + free(name); + if (value == NULL) + return (NULL); + if (end == NULL) + end = ""; + xasprintf(&expanded, "%s%s", value->value, end); + return (expanded); + } + + return (xstrdup(path)); +} + +void +expand_paths(const char *s, char ***paths, u_int *n) +{ + const char *home = find_home(); + char *copy, *next, *tmp, resolved[PATH_MAX], *expanded; + u_int i; + + *paths = NULL; + *n = 0; + + copy = tmp = xstrdup(s); + while ((next = strsep(&tmp, ":")) != NULL) { + expanded = expand_path(next, home); + if (expanded == NULL) { + log_debug("%s: invalid path: %s", __func__, next); + continue; + } + if (realpath(expanded, resolved) == NULL) { + log_debug("%s: realpath(\"%s\") failed: %s", __func__, + expanded, strerror(errno)); + free(expanded); + continue; + } + free(expanded); + for (i = 0; i < *n; i++) { + if (strcmp(resolved, (*paths)[i]) == 0) + break; + } + if (i != *n) { + log_debug("%s: duplicate path: %s", __func__, resolved); + continue; + } + *paths = xreallocarray(*paths, (*n) + 1, sizeof *paths); + (*paths)[(*n)++] = xstrdup(resolved); + } + free(copy); +} + static char * make_label(const char *label, char **cause) { - char *base, resolved[PATH_MAX], *path, *s; - struct stat sb; - uid_t uid; + char **paths, *path, *base; + u_int i, n; + struct stat sb; + uid_t uid; *cause = NULL; - if (label == NULL) label = "default"; uid = getuid(); - if ((s = getenv("TMUX_TMPDIR")) != NULL && *s != '\0') - xasprintf(&base, "%s/tmux-%ld", s, (long)uid); - else - xasprintf(&base, "%s/tmux-%ld", _PATH_TMP, (long)uid); - if (realpath(base, resolved) == NULL && - strlcpy(resolved, base, sizeof resolved) >= sizeof resolved) { - errno = ERANGE; - free(base); - goto fail; + expand_paths(TMUX_SOCK, &paths, &n); + if (n == 0) { + xasprintf(cause, "no suitable socket path"); + return (NULL); } - free(base); + path = paths[0]; /* can only have one socket! */ + for (i = 1; i < n; i++) + free(paths[i]); + free(paths); - if (mkdir(resolved, S_IRWXU) != 0 && errno != EEXIST) + xasprintf(&base, "%s/tmux-%ld", path, (long)uid); + if (mkdir(base, S_IRWXU) != 0 && errno != EEXIST) goto fail; - if (lstat(resolved, &sb) != 0) + if (lstat(base, &sb) != 0) goto fail; if (!S_ISDIR(sb.st_mode)) { errno = ENOTDIR; @@ -146,11 +216,13 @@ make_label(const char *label, char **cause) errno = EACCES; goto fail; } - xasprintf(&path, "%s/%s", resolved, label); + xasprintf(&path, "%s/%s", base, label); + free(base); return (path); fail: - xasprintf(cause, "error creating %s (%s)", resolved, strerror(errno)); + xasprintf(cause, "error creating %s (%s)", base, strerror(errno)); + free(base); return (NULL); } diff --git a/tmux.h b/tmux.h index 97024310..cf8bbbf5 100644 --- a/tmux.h +++ b/tmux.h @@ -63,10 +63,13 @@ struct winlink; /* Client-server protocol version. */ #define PROTOCOL_VERSION 8 -/* Default configuration files. */ +/* Default configuration files and socket paths. */ #ifndef TMUX_CONF #define TMUX_CONF "/etc/tmux.conf:~/.tmux.conf" #endif +#ifndef TMUX_SOCK +#define TMUX_SOCK "$TMUX_TMPDIR:" _PATH_TMP +#endif /* Minimum layout cell size, NOT including border lines. */ #define PANE_MINIMUM 1 @@ -1746,6 +1749,8 @@ const char *sig2name(int); const char *find_cwd(void); const char *find_home(void); const char *getversion(void); +void expand_paths(const char *, char ***, u_int *); + /* proc.c */ struct imsg; diff --git a/tty-features.c b/tty-features.c index 9eb446d4..7505c96b 100644 --- a/tty-features.c +++ b/tty-features.c @@ -27,7 +27,7 @@ * Still hardcoded: * - bracket paste (sent if application asks for it); * - mouse (under kmous capability); - * - focus events (under focus-events option); + * - focus events (under XT and focus-events option); * - default colours (under AX or op capabilities); * - AIX colours (under colors >= 16); * - alternate escape (under XT). -- cgit From 26312a7774f9752ac391017be0705e3a62dc525b Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:30:17 +0000 Subject: Move terminal features into a single file. --- tty-keys.c | 55 +++++++++++++++---------------------------------------- 1 file changed, 15 insertions(+), 40 deletions(-) diff --git a/tty-keys.c b/tty-keys.c index 8c778b2a..f5a3418f 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -1070,28 +1070,13 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len, ","); break; case 'M': /* mintty */ - tty_add_features(&c->term_features, - "256," - "RGB," - "title", - ","); + tty_default_features(&c->term_features, "mintty", 0); break; case 'T': /* tmux */ - tty_add_features(&c->term_features, - "256," - "RGB," - "ccolour," - "cstyle," - "overline," - "title," - "usstyle", - ","); + tty_default_features(&c->term_features, "tmux", 0); break; case 'U': /* rxvt-unicode */ - tty_add_features(&c->term_features, - "256," - "title", - ","); + tty_default_features(&c->term_features, "rxvt-unicode", 0); break; } log_debug("%s: received secondary DA %.*s", c->name, (int)*size, buf); @@ -1112,7 +1097,7 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf, { struct client *c = tty->client; u_int i; - char tmp[64]; + char tmp[128]; *size = 0; if (tty->flags & TTY_HAVEXDA) @@ -1150,29 +1135,19 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf, *size = 5 + i; /* Add terminal features. */ - if (strncmp(tmp, "iTerm2 ", 7) == 0) { - tty_add_features(&c->term_features, - "256," - "RGB," - "clipboard," - "cstyle," - "margins," - "sync," - "title", - ","); - } else if (strncmp(tmp, "tmux ", 5) == 0) { - tty_add_features(&c->term_features, - "256," - "RGB," - "ccolour," - "cstyle," - "overline," - "title," - "usstyle", - ","); - } + if (strncmp(tmp, "iTerm2 ", 7) == 0) + tty_default_features(&c->term_features, "iTerm2", 0); + 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); + 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); + free(c->term_type); + c->term_type = xstrdup(tmp); + tty_update_features(tty); tty->flags |= TTY_HAVEXDA; -- cgit From aebeeec1e988bd74e273bbf6e79f8950895c38fd Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:39:40 +0000 Subject: Add feature and capabilities for focus reporting. Also document AX and XT even though they aren't tmux's, and add some bits for rxvt. --- tmux.1 | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tmux.1 b/tmux.1 index daa0739c..7918c780 100644 --- a/tmux.1 +++ b/tmux.1 @@ -4463,7 +4463,8 @@ The following variables are available, where appropriate: .It Li "client_readonly" Ta "" Ta "1 if client is readonly" .It Li "client_session" Ta "" Ta "Name of the client's session" .It Li "client_termname" Ta "" Ta "Terminal name of client" -.It Li "client_termfeatures" Ta "" Ta "Terminal features of client" +.It Li "client_termtype" Ta "" Ta "Terminal type of client, if available" +.It Li "client_termfeatures" Ta "" Ta "Terminal features of client, if any" .It Li "client_tty" Ta "" Ta "Pseudo terminal of client" .It Li "client_utf8" Ta "" Ta "1 if client supports UTF-8" .It Li "client_width" Ta "" Ta "Width of client" @@ -5555,6 +5556,10 @@ It is not normally necessary to set these manually, instead the .Ic terminal-features option should be used. .Bl -tag -width Ds +.It Em \&AX +An existing extension that tells +.Nm +the terminal supports default colours. .It Em \&Cs , Cr Set the cursor colour. The first takes a single string argument and is used to set the colour; @@ -5567,6 +5572,19 @@ $ printf '\e033]12;red\e033\e\e' .Ed .It Em \&Cmg, \&Clmg, \&Dsmg , \&Enmg Set, clear, disable or enable DECSLRM margins. +These are set automatically if the terminal reports it is +.Em VT420 +compatible. +.It Em \&Dsbp , \&Enbp +Disable and enable bracketed paste. +These are set automatically if the +.Em XT +capability is present. +.It Em \&Dsfcs , \&Enfcs +Disable and enable focus reporting. +These are set automatically if the +.Em XT +capability is present. .It Em \&Smol Enable the overline attribute. .It Em \&Smulx @@ -5617,6 +5635,11 @@ See the option above and the .Xr xterm 1 man page. +.It Em \&XT +This is an existing extension capability that tmux uses to mean that the +terminal supports the +.Xr xterm 1 +title set sequences and to automatically set some of the capabilities above. .El .Sh CONTROL MODE .Nm -- cgit From 21a39c997b82b50b0307e836e4f11f9db6a84e55 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:42:06 +0000 Subject: Do not redraw or update mode if nothing has changed. --- screen-redraw.c | 5 +++++ server-client.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/screen-redraw.c b/screen-redraw.c index 8e74fe97..5ca6024d 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -434,7 +434,11 @@ screen_redraw_screen(struct client *c) return; flags = screen_redraw_update(c, c->flags); + if ((flags & CLIENT_ALLREDRAWFLAGS) == 0) + return; + screen_redraw_set_context(c, &ctx); + tty_update_mode(&c->tty, c->tty.mode, NULL); tty_sync_start(&c->tty); if (flags & (CLIENT_REDRAWWINDOW|CLIENT_REDRAWBORDERS)) { @@ -470,6 +474,7 @@ screen_redraw_pane(struct client *c, struct window_pane *wp) return; screen_redraw_set_context(c, &ctx); + tty_update_mode(&c->tty, c->tty.mode, NULL); tty_sync_start(&c->tty); screen_redraw_draw_pane(&ctx, wp); diff --git a/server-client.c b/server-client.c index eb29aebb..ed138f8e 100644 --- a/server-client.c +++ b/server-client.c @@ -296,7 +296,9 @@ server_client_lost(struct client *c) if (c->flags & CLIENT_TERMINAL) tty_free(&c->tty); free(c->ttyname); + free(c->term_name); + free(c->term_type); status_free(c); @@ -1780,7 +1782,6 @@ server_client_check_redraw(struct client *c) if (!redraw) continue; log_debug("%s: redrawing pane %%%u", __func__, wp->id); - tty_update_mode(tty, mode, NULL); screen_redraw_pane(c, wp); } c->redraw_panes = 0; @@ -1788,7 +1789,6 @@ server_client_check_redraw(struct client *c) } if (c->flags & CLIENT_ALLREDRAWFLAGS) { - tty_update_mode(tty, mode, NULL); if (options_get_number(s->options, "set-titles")) server_client_set_title(c); screen_redraw_screen(c); -- cgit From 7dbe623156e7b0e32e10e5e6445b7b7e448cc3a2 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:46:14 +0000 Subject: Instead of having a default set of terminals in terminal-overrides that get XT added and using that as a marker for xterm(1)-like, assume that if the terminfo(5) entry already has XT or the clear capability starts with CSI then the terminal is VT100-like and it should be safe to send DA requests. The DA responses trigger additional features being added. --- options-table.c | 2 +- tty-features.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++--------- tty-term.c | 30 +++++++++++----- 3 files changed, 110 insertions(+), 27 deletions(-) diff --git a/options-table.c b/options-table.c index 23e5af6f..eaa7c2a7 100644 --- a/options-table.c +++ b/options-table.c @@ -261,7 +261,7 @@ const struct options_table_entry options_table[] = { .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SERVER, .flags = OPTIONS_TABLE_IS_ARRAY, - .default_str = "tmux*:XT,screen*:XT,xterm*:XT", + .default_str = "", .separator = "," }, diff --git a/tty-features.c b/tty-features.c index 7505c96b..30d3d1a0 100644 --- a/tty-features.c +++ b/tty-features.c @@ -25,15 +25,12 @@ /* * Still hardcoded: - * - bracket paste (sent if application asks for it); * - mouse (under kmous capability); - * - focus events (under XT and focus-events option); * - default colours (under AX or op capabilities); * - AIX colours (under colors >= 16); - * - alternate escape (under XT). + * - alternate escape (if terminal is VT100-like). * * Also: - * - XT is used to decide whether to send DA and XDA; * - DECFRA uses a flag instead of capabilities; * - UTF-8 is a separate flag on the client; needed for unattached clients. */ @@ -51,7 +48,7 @@ static const char *tty_feature_title_capabilities[] = { "fsl=\\a", NULL }; -static struct tty_feature tty_feature_title = { +static const struct tty_feature tty_feature_title = { "title", tty_feature_title_capabilities, 0 @@ -62,7 +59,7 @@ static const char *tty_feature_clipboard_capabilities[] = { "Ms=\\E]52;%p1%s;%p2%s\\a", NULL }; -static struct tty_feature tty_feature_clipboard = { +static const struct tty_feature tty_feature_clipboard = { "clipboard", tty_feature_clipboard_capabilities, 0 @@ -81,7 +78,7 @@ static const char *tty_feature_rgb_capabilities[] = { "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", NULL }; -static struct tty_feature tty_feature_rgb = { +static const struct tty_feature tty_feature_rgb = { "RGB", tty_feature_rgb_capabilities, TERM_256COLOURS|TERM_RGBCOLOURS @@ -94,7 +91,7 @@ static const char *tty_feature_256_capabilities[] = { "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", NULL }; -static struct tty_feature tty_feature_256 = { +static const struct tty_feature tty_feature_256 = { "256", tty_feature_256_capabilities, TERM_256COLOURS @@ -105,7 +102,7 @@ static const char *tty_feature_overline_capabilities[] = { "Smol=\\E[53m", NULL }; -static struct tty_feature tty_feature_overline = { +static const struct tty_feature tty_feature_overline = { "overline", tty_feature_overline_capabilities, 0 @@ -117,19 +114,43 @@ static const char *tty_feature_usstyle_capabilities[] = { "Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m", NULL }; -static struct tty_feature tty_feature_usstyle = { +static const struct tty_feature tty_feature_usstyle = { "usstyle", tty_feature_usstyle_capabilities, 0 }; +/* Terminal supports bracketed paste. */ +static const char *tty_feature_bpaste_capabilities[] = { + "Enbp=\\E[?2004h", + "Dsbp=\\E[?2004l", + NULL +}; +static const struct tty_feature tty_feature_bpaste = { + "bpaste", + tty_feature_bpaste_capabilities, + 0 +}; + +/* Terminal supports focus reporting. */ +static const char *tty_feature_focus_capabilities[] = { + "Enfcs=\\E[?1004h", + "Dsfcs=\\E[?1004l", + NULL +}; +static const struct tty_feature tty_feature_focus = { + "focus", + tty_feature_focus_capabilities, + 0 +}; + /* Terminal supports cursor styles. */ static const char *tty_feature_cstyle_capabilities[] = { "Ss=\\E[%p1%d q", "Se=\\E[2 q", NULL }; -static struct tty_feature tty_feature_cstyle = { +static const struct tty_feature tty_feature_cstyle = { "cstyle", tty_feature_cstyle_capabilities, 0 @@ -141,18 +162,29 @@ static const char *tty_feature_ccolour_capabilities[] = { "Cr=\\E]112\\a", NULL }; -static struct tty_feature tty_feature_ccolour = { +static const struct tty_feature tty_feature_ccolour = { "ccolour", tty_feature_ccolour_capabilities, 0 }; +/* Terminal supports strikethrough. */ +static const char *tty_feature_strikethrough_capabilities[] = { + "smxx=\\E[9m", + NULL +}; +static const struct tty_feature tty_feature_strikethrough = { + "strikethrough", + tty_feature_strikethrough_capabilities, + 0 +}; + /* Terminal supports synchronized updates. */ static const char *tty_feature_sync_capabilities[] = { "Sync=\\EP=%p1%ds\\E\\\\", NULL }; -static struct tty_feature tty_feature_sync = { +static const struct tty_feature tty_feature_sync = { "sync", tty_feature_sync_capabilities, 0 @@ -166,14 +198,14 @@ static const char *tty_feature_margins_capabilities[] = { "Cmg=\\E[%i%p1%d;%p2%ds", NULL }; -static struct tty_feature tty_feature_margins = { +static const struct tty_feature tty_feature_margins = { "margins", tty_feature_margins_capabilities, TERM_DECSLRM }; /* Terminal supports DECFRA rectangle fill. */ -static struct tty_feature tty_feature_rectfill = { +static const struct tty_feature tty_feature_rectfill = { "rectfill", NULL, TERM_DECFRA @@ -182,13 +214,16 @@ static struct tty_feature tty_feature_rectfill = { /* Available terminal features. */ static const struct tty_feature *tty_features[] = { &tty_feature_256, - &tty_feature_clipboard, + &tty_feature_bpaste, &tty_feature_ccolour, + &tty_feature_clipboard, &tty_feature_cstyle, + &tty_feature_focus, &tty_feature_margins, &tty_feature_overline, &tty_feature_rectfill, &tty_feature_rgb, + &tty_feature_strikethrough, &tty_feature_sync, &tty_feature_title, &tty_feature_usstyle @@ -201,7 +236,7 @@ tty_add_features(int *feat, const char *s, const char *separators) char *next, *loop, *copy; u_int i; - log_debug("%s: %s", __func__, s); + log_debug("adding terminal features %s", s); loop = copy = xstrdup(s); while ((next = strsep(&loop, separators)) != NULL) { @@ -275,3 +310,39 @@ tty_apply_features(struct tty_term *term, int feat) term->features |= feat; return (1); } + +void +tty_default_features(int *feat, const char *name, u_int version) +{ + static struct { + const char *name; + u_int version; + const char *features; + } 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" + }, + { .name = "tmux", + .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,focus,overline,usstyle" + }, + { .name = "rxvt-unicode", + .features = "256,bpaste,ccolour,cstyle,title" + }, + { .name = "iTerm2", + .features = TTY_FEATURES_BASE_MODERN_XTERM ",cstyle,margins,sync" + }, + { .name = "XTerm", + .features = TTY_FEATURES_BASE_MODERN_XTERM ",ccolour,cstyle,focus,margins,rectfill" + } + }; + u_int i; + + for (i = 0; i < nitems(table); i++) { + if (strcmp(table[i].name, name) != 0) + continue; + if (version != 0 && version < table[i].version) + continue; + tty_add_features(feat, table[i].features, ","); + } +} diff --git a/tty-term.c b/tty-term.c index 78ba5a37..67ca1bac 100644 --- a/tty-term.c +++ b/tty-term.c @@ -83,6 +83,8 @@ 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_DSFCS] = { TTYCODE_STRING, "Dsfcs" }, + [TTYC_DSBP] = { TTYCODE_STRING, "Dsbp" }, [TTYC_DSMG] = { TTYCODE_STRING, "Dsmg" }, [TTYC_E3] = { TTYCODE_STRING, "E3" }, [TTYC_ECH] = { TTYCODE_STRING, "ech" }, @@ -90,6 +92,8 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_EL1] = { TTYCODE_STRING, "el1" }, [TTYC_EL] = { TTYCODE_STRING, "el" }, [TTYC_ENACS] = { TTYCODE_STRING, "enacs" }, + [TTYC_ENBP] = { TTYCODE_STRING, "Enbp" }, + [TTYC_ENFCS] = { TTYCODE_STRING, "Enfcs" }, [TTYC_ENMG] = { TTYCODE_STRING, "Enmg" }, [TTYC_FSL] = { TTYCODE_STRING, "fsl" }, [TTYC_HOME] = { TTYCODE_STRING, "home" }, @@ -545,21 +549,29 @@ tty_term_create(struct tty *tty, char *name, int *feat, int fd, char **cause) goto error; } - /* These can be emulated so one of the two is required. */ - if (!tty_term_has(term, TTYC_CUD1) && !tty_term_has(term, TTYC_CUD)) { - xasprintf(cause, "terminal does not support cud1 or cud"); - goto error; + /* + * If TERM has XT or clear starts with CSI then it is safe to assume + * the terminal is derived from the VT100. This controls whether device + * attributes requests are sent to get more information. + * + * This is a bit of a hack but there aren't that many alternatives. + * Worst case tmux will just fall back to using whatever terminfo(5) + * says without trying to correct anything that is missing. + * + * Also add few features that VT100-like terminals should either + * support or safely ignore. + */ + s = tty_term_string(term, TTYC_CLEAR); + if (tty_term_flag(term, TTYC_XT) || strncmp(s, "\033[", 2) == 0) { + term->flags |= TERM_VT100LIKE; + tty_add_features(feat, "bpaste,focus,title", ","); } /* Add RGB feature if terminal has RGB colours. */ if ((tty_term_flag(term, TTYC_TC) || tty_term_has(term, TTYC_RGB)) && (!tty_term_has(term, TTYC_SETRGBF) || !tty_term_has(term, TTYC_SETRGBB))) - tty_add_features(feat, "RGB", ":,"); - - /* Add feature if terminal has XT. */ - if (tty_term_flag(term, TTYC_XT)) - tty_add_features(feat, "title", ":,"); + tty_add_features(feat, "RGB", ","); /* Apply the features and overrides again. */ tty_apply_features(term, *feat); -- cgit From 428137d8765f6aeb56503d8d37e3b1c9b33994ce Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:49:50 +0000 Subject: Instead of forbidding invalid session names, sanitize them like window names. --- cmd-new-session.c | 35 ++++++++++++++--------------------- cmd-rename-session.c | 12 ++++-------- session.c | 19 ++++++++++++++----- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/cmd-new-session.c b/cmd-new-session.c index 353f7bed..f08155c0 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -70,13 +70,14 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) struct cmd_find_state *current = cmdq_get_current(item); struct cmd_find_state *target = cmdq_get_target(item); struct client *c = cmdq_get_client(item); - struct session *s, *as, *groupwith; + struct session *s, *as, *groupwith = NULL; struct environ *env; struct options *oo; struct termios tio, *tiop; - struct session_group *sg; - const char *errstr, *template, *group, *prefix, *tmp; + struct session_group *sg = NULL; + const char *errstr, *template, *group, *tmp; char *cause, *cwd = NULL, *cp, *newname = NULL; + char *name, *prefix = NULL; int detached, already_attached, is_control = 0; u_int sx, sy, dsx, dsy; struct spawn_context sc; @@ -98,11 +99,9 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) tmp = args_get(args, 's'); if (tmp != NULL) { - newname = format_single(item, tmp, c, NULL, NULL, NULL); - if (!session_check_name(newname)) { - cmdq_error(item, "bad session name: %s", newname); - goto fail; - } + name = format_single(item, tmp, c, NULL, NULL, NULL); + newname = session_check_name(name); + free(name); } if (args_has(args, 'A')) { if (newname != NULL) @@ -126,24 +125,16 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) group = args_get(args, 't'); if (group != NULL) { groupwith = target->s; - if (groupwith == NULL) { - if (!session_check_name(group)) { - cmdq_error(item, "bad group name: %s", group); - goto fail; - } + if (groupwith == NULL) sg = session_group_find(group); - } else + else sg = session_group_contains(groupwith); if (sg != NULL) - prefix = sg->name; + prefix = xstrdup(sg->name); else if (groupwith != NULL) - prefix = groupwith->name; + prefix = xstrdup(groupwith->name); else - prefix = group; - } else { - groupwith = NULL; - sg = NULL; - prefix = NULL; + prefix = session_check_name(group); } /* Set -d if no client. */ @@ -353,10 +344,12 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) free(cwd); free(newname); + free(prefix); return (CMD_RETURN_NORMAL); fail: free(cwd); free(newname); + free(prefix); return (CMD_RETURN_ERROR); } diff --git a/cmd-rename-session.c b/cmd-rename-session.c index 4b2c3d88..51b8ffc8 100644 --- a/cmd-rename-session.c +++ b/cmd-rename-session.c @@ -49,19 +49,15 @@ cmd_rename_session_exec(struct cmd *self, struct cmdq_item *item) struct args *args = cmd_get_args(self); struct cmd_find_state *target = cmdq_get_target(item); struct session *s = target->s; - char *newname; + char *newname, *tmp; - newname = format_single_from_target(item, args->argv[0]); + tmp = format_single_from_target(item, args->argv[0]); + newname = session_check_name(tmp); + free(tmp); if (strcmp(newname, s->name) == 0) { free(newname); return (CMD_RETURN_NORMAL); } - - if (!session_check_name(newname)) { - cmdq_error(item, "bad session name: %s", newname); - free(newname); - return (CMD_RETURN_ERROR); - } if (session_find(newname) != NULL) { cmdq_error(item, "duplicate session: %s", newname); free(newname); diff --git a/session.c b/session.c index be9c8e07..93d50b47 100644 --- a/session.c +++ b/session.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "tmux.h" @@ -123,7 +124,6 @@ session_create(const char *prefix, const char *name, const char *cwd, s->cwd = xstrdup(cwd); - s->curw = NULL; TAILQ_INIT(&s->lastw); RB_INIT(&s->windows); @@ -142,7 +142,6 @@ session_create(const char *prefix, const char *name, const char *cwd, s->name = xstrdup(name); s->id = next_session_id++; } else { - s->name = NULL; do { s->id = next_session_id++; free(s->name); @@ -232,11 +231,20 @@ session_destroy(struct session *s, int notify, const char *from) session_remove_ref(s, __func__); } -/* Check a session name is valid: not empty and no colons or periods. */ -int +/* Sanitize session name. */ +char * session_check_name(const char *name) { - return (*name != '\0' && name[strcspn(name, ":.")] == '\0'); + char *copy, *cp, *new_name; + + copy = xstrdup(name); + for (cp = copy; *cp != '\0'; cp++) { + if (*cp == ':' || *cp == '.') + *cp = '_'; + } + utf8_stravis(&new_name, copy, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL); + free(copy); + return (new_name); } /* Lock session if it has timed out. */ @@ -556,6 +564,7 @@ session_group_remove(struct session *s) TAILQ_REMOVE(&sg->sessions, s, gentry); if (TAILQ_EMPTY(&sg->sessions)) { RB_REMOVE(session_groups, &session_groups, sg); + free((void *)sg->name); free(sg); } } -- cgit From 5bf96c2f2c40e93b8e66d7100f7b3dc9074a1ca6 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:53:23 +0000 Subject: Use a grid cell not a style for the pane style. --- grid.c | 23 ++++++++++++++++------- menu.c | 4 ++-- style.c | 29 ++--------------------------- tmux.h | 24 +++++++++++++++++++----- tty.c | 57 ++++++++++++++++++++++++--------------------------------- window.c | 18 +++++++++--------- 6 files changed, 72 insertions(+), 83 deletions(-) diff --git a/grid.c b/grid.c index 0cef412b..81f3709c 100644 --- a/grid.c +++ b/grid.c @@ -211,19 +211,28 @@ grid_check_y(struct grid *gd, const char *from, u_int py) return (0); } -/* Compare grid cells. Return 1 if equal, 0 if not. */ +/* Check if two styles are (visibly) the same. */ int -grid_cells_equal(const struct grid_cell *gca, const struct grid_cell *gcb) +grid_cells_look_equal(const struct grid_cell *gc1, const struct grid_cell *gc2) { - if (gca->fg != gcb->fg || gca->bg != gcb->bg) + if (gc1->fg != gc2->fg || gc1->bg != gc2->bg) + return (0); + if (gc1->attr != gc2->attr || gc1->flags != gc2->flags) return (0); - if (gca->attr != gcb->attr || gca->flags != gcb->flags) + return (1); +} + +/* Compare grid cells. Return 1 if equal, 0 if not. */ +int +grid_cells_equal(const struct grid_cell *gc1, const struct grid_cell *gc2) +{ + if (!grid_cells_look_equal(gc1, gc2)) return (0); - if (gca->data.width != gcb->data.width) + if (gc1->data.width != gc2->data.width) return (0); - if (gca->data.size != gcb->data.size) + if (gc1->data.size != gc2->data.size) return (0); - return (memcmp(gca->data.data, gcb->data.data, gca->data.size) == 0); + return (memcmp(gc1->data.data, gc2->data.data, gc1->data.size) == 0); } /* Free one line. */ diff --git a/menu.c b/menu.c index 39cb50c7..fd744e7d 100644 --- a/menu.c +++ b/menu.c @@ -73,7 +73,7 @@ menu_add_item(struct menu *menu, const struct menu_item *item, return; if (fs != NULL) - s = format_single(qitem, item->name, c, fs->s, fs->wl, fs->wp); + s = format_single_from_state(qitem, item->name, c, fs); else s = format_single(qitem, item->name, c, NULL, NULL, NULL); if (*s == '\0') { /* no item if empty after format expanded */ @@ -91,7 +91,7 @@ menu_add_item(struct menu *menu, const struct menu_item *item, cmd = item->command; if (cmd != NULL) { if (fs != NULL) - s = format_single(qitem, cmd, c, fs->s, fs->wl, fs->wp); + s = format_single_from_state(qitem, cmd, c, fs); else s = format_single(qitem, cmd, c, NULL, NULL, NULL); } else diff --git a/style.c b/style.c index da3b4c78..2ac78e97 100644 --- a/style.c +++ b/style.c @@ -59,6 +59,7 @@ style_parse(struct style *sy, const struct grid_cell *base, const char *in) return (0); style_copy(&saved, sy); + log_debug("%s: %s", __func__, in); do { while (*in != '\0' && strchr(delimiters, *in) != NULL) in++; @@ -71,6 +72,7 @@ style_parse(struct style *sy, const struct grid_cell *base, const char *in) memcpy(tmp, in, end); tmp[end] = '\0'; + log_debug("%s: %s", __func__, tmp); if (strcasecmp(tmp, "default") == 0) { sy->gc.fg = base->fg; sy->gc.bg = base->bg; @@ -285,30 +287,3 @@ style_copy(struct style *dst, struct style *src) { memcpy(dst, src, sizeof *dst); } - -/* Check if two styles are (visibly) the same. */ -int -style_equal(struct style *sy1, struct style *sy2) -{ - struct grid_cell *gc1 = &sy1->gc; - struct grid_cell *gc2 = &sy2->gc; - - if (gc1->fg != gc2->fg) - return (0); - if (gc1->bg != gc2->bg) - return (0); - if ((gc1->attr & STYLE_ATTR_MASK) != (gc2->attr & STYLE_ATTR_MASK)) - return (0); - if (sy1->fill != sy2->fill) - return (0); - if (sy1->align != sy2->align) - return (0); - return (1); -} - -/* Is this style default? */ -int -style_is_default(struct style *sy) -{ - return (style_equal(sy, &style_default)); -} diff --git a/tmux.h b/tmux.h index cf8bbbf5..4e19c4ef 100644 --- a/tmux.h +++ b/tmux.h @@ -279,6 +279,8 @@ enum tty_code_code { TTYC_DIM, TTYC_DL, TTYC_DL1, + TTYC_DSBP, + TTYC_DSFCS, TTYC_DSMG, TTYC_E3, TTYC_ECH, @@ -286,6 +288,8 @@ enum tty_code_code { TTYC_EL, TTYC_EL1, TTYC_ENACS, + TTYC_ENBP, + TTYC_ENFCS, TTYC_ENMG, TTYC_FSL, TTYC_HOME, @@ -924,8 +928,8 @@ struct window_pane { struct input_ctx *ictx; - struct style cached_style; - struct style cached_active_style; + struct grid_cell cached_gc; + struct grid_cell cached_active_gc; int *palette; int pipe_fd; @@ -1196,6 +1200,7 @@ struct tty_term { #define TERM_DECSLRM 0x4 #define TERM_DECFRA 0x8 #define TERM_RGBCOLOURS 0x10 +#define TERM_VT100LIKE 0x20 int flags; LIST_ENTRY(tty_term) entry; @@ -1504,6 +1509,7 @@ struct client { char *term_name; int term_features; + char *term_type; char *ttyname; struct tty tty; @@ -1819,7 +1825,14 @@ char *format_expand(struct format_tree *, const char *); char *format_single(struct cmdq_item *, const char *, struct client *, struct session *, struct winlink *, struct window_pane *); +char *format_single_from_state(struct cmdq_item *, const char *, + struct client *, struct cmd_find_state *); char *format_single_from_target(struct cmdq_item *, const char *); +struct format_tree *format_create_defaults(struct cmdq_item *, struct client *, + struct session *, struct winlink *, struct window_pane *); +struct format_tree *format_create_from_state(struct cmdq_item *, + struct client *, struct cmd_find_state *); +struct format_tree *format_create_from_target(struct cmdq_item *); void format_defaults(struct format_tree *, struct client *, struct session *, struct winlink *, struct window_pane *); void format_defaults_window(struct format_tree *, struct window *); @@ -2028,6 +2041,7 @@ const char *tty_term_describe(struct tty_term *, enum tty_code_code); void tty_add_features(int *, const char *, const char *); const char *tty_get_features(int); int tty_apply_features(struct tty_term *, int); +void tty_default_features(int *, const char *, u_int); /* tty-acs.c */ int tty_acs_needed(struct tty *); @@ -2349,6 +2363,8 @@ int attributes_fromstring(const char *); extern const struct grid_cell grid_default_cell; void grid_empty_line(struct grid *, u_int, u_int); int grid_cells_equal(const struct grid_cell *, const struct grid_cell *); +int grid_cells_look_equal(const struct grid_cell *, + const struct grid_cell *); struct grid *grid_create(u_int, u_int, u_int); void grid_destroy(struct grid *); int grid_compare(struct grid *, struct grid *); @@ -2713,7 +2729,7 @@ struct session *session_create(const char *, const char *, const char *, void session_destroy(struct session *, int, const char *); void session_add_ref(struct session *, const char *); void session_remove_ref(struct session *, const char *); -int session_check_name(const char *); +char *session_check_name(const char *); void session_update_activity(struct session *, struct timeval *); struct session *session_next_session(struct session *); struct session *session_previous_session(struct session *); @@ -2804,10 +2820,8 @@ int style_parse(struct style *,const struct grid_cell *, const char *style_tostring(struct style *); void style_apply(struct grid_cell *, struct options *, const char *); -int style_equal(struct style *, struct style *); void style_set(struct style *, const struct grid_cell *); void style_copy(struct style *, struct style *); -int style_is_default(struct style *); /* spawn.c */ struct winlink *spawn_window(struct spawn_context *, char **); diff --git a/tty.c b/tty.c index 5d84c9e8..99b433ae 100644 --- a/tty.c +++ b/tty.c @@ -330,13 +330,12 @@ tty_start_tty(struct tty *tty) tty_puts(tty, "\033[?1006l\033[?1005l"); } - if (tty_term_flag(tty->term, TTYC_XT)) { - if (options_get_number(global_options, "focus-events")) { - tty->flags |= TTY_FOCUS; - tty_puts(tty, "\033[?1004h"); - } - tty_puts(tty, "\033[?7727h"); + 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); @@ -358,7 +357,7 @@ tty_send_requests(struct tty *tty) if (~tty->flags & TTY_STARTED) return; - if (tty_term_flag(tty->term, TTYC_XT)) { + if (tty->term->flags & TERM_VT100LIKE) { if (~tty->flags & TTY_HAVEDA) tty_puts(tty, "\033[>c"); if (~tty->flags & TTY_HAVEXDA) @@ -407,7 +406,7 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, tty_term_string1(tty->term, TTYC_SS, 0)); } if (tty->mode & MODE_BRACKETPASTE) - tty_raw(tty, "\033[?2004l"); + tty_raw(tty, tty_term_string(tty->term, TTYC_DSBP)); if (*tty->ccolour != '\0') tty_raw(tty, tty_term_string(tty->term, TTYC_CR)); @@ -417,13 +416,12 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, "\033[?1006l\033[?1005l"); } - if (tty_term_flag(tty->term, TTYC_XT)) { - if (tty->flags & TTY_FOCUS) { - tty->flags &= ~TTY_FOCUS; - tty_raw(tty, "\033[?1004l"); - } - tty_raw(tty, "\033[?7727l"); + 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"); if (tty_use_margin(tty)) tty_raw(tty, tty_term_string(tty->term, TTYC_DSMG)); @@ -676,7 +674,8 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s) mode &= ~MODE_CURSOR; changed = mode ^ tty->mode; - log_debug("%s: update mode %x to %x", c->name, tty->mode, mode); + if (changed != 0) + log_debug("%s: update mode %x to %x", c->name, tty->mode, mode); if (changed & MODE_BLINKING) { if (tty_term_has(tty->term, TTYC_CVVIS)) @@ -729,9 +728,9 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s) } if (changed & MODE_BRACKETPASTE) { if (mode & MODE_BRACKETPASTE) - tty_puts(tty, "\033[?2004h"); + tty_putcode(tty, TTYC_ENBP); else - tty_puts(tty, "\033[?2004l"); + tty_putcode(tty, TTYC_DSBP); } tty->mode = mode; } @@ -2691,27 +2690,19 @@ static void tty_default_colours(struct grid_cell *gc, struct window_pane *wp) { struct options *oo = wp->options; - struct style *style, *active_style; int c; if (wp->flags & PANE_STYLECHANGED) { wp->flags &= ~PANE_STYLECHANGED; - - active_style = options_get_style(oo, "window-active-style"); - style = options_get_style(oo, "window-style"); - - style_copy(&wp->cached_active_style, active_style