mirror of
https://github.com/tmux/tmux.git
synced 2026-08-24 07:31:36 +00:00
Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master: Allow features to be disabled using @ suffix in terminal-features, from Michael Grant.
This commit is contained in:
8
tmux.1
8
tmux.1
@@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: tmux.1,v 1.1155 2026/08/06 09:05:04 nicm Exp $
|
||||
.\" $OpenBSD: tmux.1,v 1.1156 2026/08/17 14:47:41 nicm Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
.\"
|
||||
@@ -14,7 +14,7 @@
|
||||
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: August 6 2026 $
|
||||
.Dd $Mdocdate: August 17 2026 $
|
||||
.Dt TMUX 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -5047,6 +5047,10 @@ This is an array option where each entry is a colon-separated string made up
|
||||
of a terminal type pattern (matched using
|
||||
.Xr glob 7
|
||||
patterns) followed by a list of terminal features.
|
||||
A feature may be suffixed with
|
||||
.Ql @
|
||||
to disable it; for example,
|
||||
.Ql xterm*:sync@ .
|
||||
The available features are:
|
||||
.Bl -tag -width Ds
|
||||
.It 256
|
||||
|
||||
6
tmux.c
6
tmux.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tmux.c,v 1.222 2026/07/19 19:09:30 nicm Exp $ */
|
||||
/* $OpenBSD: tmux.c,v 1.223 2026/08/17 14:47:41 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -425,7 +425,7 @@ main(int argc, char **argv)
|
||||
while ((opt = getopt(argc, argv, "2c:CDdf:hlL:NqS:T:uUvV")) != -1) {
|
||||
switch (opt) {
|
||||
case '2':
|
||||
tty_add_features(&feat, "256", ":,");
|
||||
tty_parse_features("256", ":,", &feat, NULL);
|
||||
break;
|
||||
case 'c':
|
||||
shell_command = optarg;
|
||||
@@ -473,7 +473,7 @@ main(int argc, char **argv)
|
||||
path = xstrdup(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
tty_add_features(&feat, optarg, ":,");
|
||||
tty_parse_features(optarg, ":,", &feat, NULL);
|
||||
break;
|
||||
case 'u':
|
||||
flags |= CLIENT_UTF8;
|
||||
|
||||
16
tmux.h
16
tmux.h
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tmux.h,v 1.1423 2026/08/17 07:56:56 nicm Exp $ */
|
||||
/* $OpenBSD: tmux.h,v 1.1424 2026/08/17 14:47:41 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -1718,7 +1718,7 @@ struct key_event {
|
||||
struct tty_term {
|
||||
char *name;
|
||||
struct tty *tty;
|
||||
int features;
|
||||
int applied_features;
|
||||
|
||||
char acs[UCHAR_MAX + 1][2];
|
||||
|
||||
@@ -2226,6 +2226,7 @@ struct client {
|
||||
|
||||
char *term_name;
|
||||
int term_features;
|
||||
int term_nofeatures;
|
||||
char *term_type;
|
||||
char **term_caps;
|
||||
u_int term_ncaps;
|
||||
@@ -2999,8 +3000,7 @@ extern struct tty_terms tty_terms;
|
||||
u_int tty_term_ncodes(void);
|
||||
void tty_term_apply(struct tty_term *, const char *, int);
|
||||
void tty_term_apply_overrides(struct tty_term *);
|
||||
struct tty_term *tty_term_create(struct tty *, char *, char **, u_int, int *,
|
||||
char **);
|
||||
struct tty_term *tty_term_create(struct tty *, char *, char **, u_int, char **);
|
||||
void tty_term_free(struct tty_term *);
|
||||
int tty_term_read_list(const char *, int, char ***, u_int *,
|
||||
char **);
|
||||
@@ -3022,11 +3022,13 @@ int tty_term_flag(struct tty_term *, enum tty_code_code);
|
||||
const char *tty_term_describe(struct tty_term *, enum tty_code_code);
|
||||
|
||||
/* tty-features.c */
|
||||
void tty_add_features(int *, const char *, const char *);
|
||||
void tty_parse_client_features(struct client *, const char *,
|
||||
const char *);
|
||||
void tty_parse_features(const char *, const char *, int *, int *);
|
||||
const char *tty_get_features(int);
|
||||
int tty_feature_present(struct tty_term *, const char *);
|
||||
int tty_apply_features(struct tty_term *, int);
|
||||
void tty_default_features(int *, const char *, u_int);
|
||||
int tty_apply_features(struct tty_term *);
|
||||
void tty_default_features(struct client *, const char *, u_int);
|
||||
|
||||
/* tty-acs.c */
|
||||
int tty_acs_needed(struct tty *);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tty-features.c,v 1.41 2026/08/17 07:52:16 nicm Exp $ */
|
||||
/* $OpenBSD: tty-features.c,v 1.42 2026/08/17 14:47:41 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -393,17 +393,29 @@ static const struct tty_feature *const tty_features[] = {
|
||||
&tty_feature_usstyle
|
||||
};
|
||||
|
||||
/* Parse features for client. */
|
||||
void
|
||||
tty_add_features(int *feat, const char *s, const char *separators)
|
||||
tty_parse_client_features(struct client *c, const char *s, const char *sep)
|
||||
{
|
||||
tty_parse_features(s, sep, &c->term_features, &c->term_nofeatures);
|
||||
}
|
||||
|
||||
/* Parse features list. */
|
||||
void
|
||||
tty_parse_features(const char *s, const char *sep, int *enabled, int *disabled)
|
||||
{
|
||||
const struct tty_feature *tf;
|
||||
char *next, *loop, *copy;
|
||||
u_int i;
|
||||
int remove;
|
||||
|
||||
log_debug("adding terminal features %s", s);
|
||||
|
||||
loop = copy = xstrdup(s);
|
||||
while ((next = strsep(&loop, separators)) != NULL) {
|
||||
while ((next = strsep(&loop, sep)) != NULL) {
|
||||
remove = (*next != '\0' && next[strlen(next) - 1] == '@');
|
||||
if (remove)
|
||||
next[strlen(next) - 1] = '\0';
|
||||
for (i = 0; i < nitems(tty_features); i++) {
|
||||
tf = tty_features[i];
|
||||
if (strcasecmp(tf->name, next) == 0)
|
||||
@@ -413,14 +425,24 @@ tty_add_features(int *feat, const char *s, const char *separators)
|
||||
log_debug("unknown terminal feature: %s", next);
|
||||
break;
|
||||
}
|
||||
if (~(*feat) & (1 << i)) {
|
||||
if (remove) {
|
||||
log_debug("removing terminal feature: %s", tf->name);
|
||||
*enabled &= ~(1 << i);
|
||||
if (disabled != NULL)
|
||||
*disabled |= 1 << i;
|
||||
continue;
|
||||
}
|
||||
if (disabled != NULL && *disabled & (1 << i))
|
||||
continue;
|
||||
if (~(*enabled) & (1 << i)) {
|
||||
log_debug("adding terminal feature: %s", tf->name);
|
||||
(*feat) |= (1 << i);
|
||||
(*enabled) |= (1 << i);
|
||||
}
|
||||
}
|
||||
free(copy);
|
||||
}
|
||||
|
||||
/* Get features as string. */
|
||||
const char *
|
||||
tty_get_features(int feat)
|
||||
{
|
||||
@@ -442,6 +464,7 @@ tty_get_features(int feat)
|
||||
return (s);
|
||||
}
|
||||
|
||||
/* Check if feature is present. */
|
||||
int
|
||||
tty_feature_present(struct tty_term *term, const char *name)
|
||||
{
|
||||
@@ -453,8 +476,8 @@ tty_feature_present(struct tty_term *term, const char *name)
|
||||
for (i = 0; i < nitems(tty_features); i++) {
|
||||
tf = tty_features[i];
|
||||
if (strcmp(tf->name, name) == 0) {
|
||||
if (term->features & (1 << i))
|
||||
return (1);
|
||||
if (term->applied_features & (1 << i))
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -481,19 +504,23 @@ tty_feature_present(struct tty_term *term, const char *name)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Apply featurs to terminal. */
|
||||
int
|
||||
tty_apply_features(struct tty_term *term, int feat)
|
||||
tty_apply_features(struct tty_term *term)
|
||||
{
|
||||
struct client *c = term->tty->client;
|
||||
const struct tty_feature *tf;
|
||||
const char *const *capability;
|
||||
int feat;
|
||||
u_int i;
|
||||
|
||||
feat = (c->term_features & ~c->term_nofeatures);
|
||||
if (feat == 0)
|
||||
return (0);
|
||||
log_debug("applying terminal features: %s", tty_get_features(feat));
|
||||
|
||||
for (i = 0; i < nitems(tty_features); i++) {
|
||||
if ((term->features & (1 << i)) || (~feat & (1 << i)))
|
||||
if ((term->applied_features & (1 << i)) || (~feat & (1 << i)))
|
||||
continue;
|
||||
tf = tty_features[i];
|
||||
|
||||
@@ -508,14 +535,15 @@ tty_apply_features(struct tty_term *term, int feat)
|
||||
}
|
||||
term->flags |= tf->flags;
|
||||
}
|
||||
if ((term->features | feat) == term->features)
|
||||
if ((term->applied_features|feat) == term->applied_features)
|
||||
return (0);
|
||||
term->features |= feat;
|
||||
term->applied_features |= feat;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Add default features for a terminal identified by name and version. */
|
||||
void
|
||||
tty_default_features(int *feat, const char *name, u_int version)
|
||||
tty_default_features(struct client *c, const char *name, u_int version)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
@@ -628,6 +656,6 @@ tty_default_features(int *feat, const char *name, u_int version)
|
||||
continue;
|
||||
if (version != 0 && version < table[i].version)
|
||||
continue;
|
||||
tty_add_features(feat, table[i].features, ",");
|
||||
tty_parse_client_features(c, table[i].features, ",");
|
||||
}
|
||||
}
|
||||
|
||||
35
tty-keys.c
35
tty-keys.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tty-keys.c,v 1.212 2026/08/17 07:52:16 nicm Exp $ */
|
||||
/* $OpenBSD: tty-keys.c,v 1.213 2026/08/17 14:47:41 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -1447,7 +1447,6 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
|
||||
size_t *size)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
int *features = &c->term_features;
|
||||
u_int i, n = 0;
|
||||
char tmp[128], *endptr, p[32] = { 0 }, *cp, *next;
|
||||
|
||||
@@ -1504,13 +1503,13 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
|
||||
for (i = 1; i < n; i++) {
|
||||
log_debug("%s: DA feature: %d", c->name, p[i]);
|
||||
if (p[i] == 4)
|
||||
tty_add_features(features, "sixel", ",");
|
||||
tty_parse_client_features(c, "sixel", ",");
|
||||
if (p[i] == 21)
|
||||
tty_add_features(features, "margins", ",");
|
||||
tty_parse_client_features(c, "margins", ",");
|
||||
if (p[i] == 28)
|
||||
tty_add_features(features, "rectfill", ",");
|
||||
tty_parse_client_features(c, "rectfill", ",");
|
||||
if (p[i] == 52)
|
||||
tty_add_features(features, "clipboard", ",");
|
||||
tty_parse_client_features(c, "clipboard", ",");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1531,7 +1530,6 @@ tty_keys_device_attributes2(struct tty *tty, const char *buf, size_t len,
|
||||
size_t *size)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
int *features = &c->term_features;
|
||||
u_int i, n = 0;
|
||||
char tmp[128], *endptr, p[32] = { 0 }, *cp, *next;
|
||||
|
||||
@@ -1585,13 +1583,13 @@ tty_keys_device_attributes2(struct tty *tty, const char *buf, size_t len,
|
||||
*/
|
||||
switch (p[0]) {
|
||||
case 'M': /* mintty */
|
||||
tty_default_features(features, "mintty", 0);
|
||||
tty_default_features(c, "mintty", 0);
|
||||
break;
|
||||
case 'T': /* tmux */
|
||||
tty_default_features(features, "tmux", 0);
|
||||
tty_default_features(c, "tmux", 0);
|
||||
break;
|
||||
case 'U': /* rxvt-unicode */
|
||||
tty_default_features(features, "rxvt-unicode", 0);
|
||||
tty_default_features(c, "rxvt-unicode", 0);
|
||||
break;
|
||||
}
|
||||
log_debug("%s: received secondary DA %.*s", c->name, (int)*size, buf);
|
||||
@@ -1611,7 +1609,6 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf,
|
||||
size_t len, size_t *size)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
int *features = &c->term_features;
|
||||
u_int i;
|
||||
char tmp[128];
|
||||
|
||||
@@ -1654,21 +1651,21 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf,
|
||||
|
||||
/* Add terminal features. */
|
||||
if (strncmp(tmp, "iTerm2 ", 7) == 0)
|
||||
tty_default_features(features, "iTerm2", 0);
|
||||
tty_default_features(c, "iTerm2", 0);
|
||||
else if (strncmp(tmp, "tmux ", 5) == 0)
|
||||
tty_default_features(features, "tmux", 0);
|
||||
tty_default_features(c, "tmux", 0);
|
||||
else if (strncmp(tmp, "XTerm(", 6) == 0)
|
||||
tty_default_features(features, "XTerm", 0);
|
||||
tty_default_features(c, "XTerm", 0);
|
||||
else if (strncmp(tmp, "mintty ", 7) == 0)
|
||||
tty_default_features(features, "mintty", 0);
|
||||
tty_default_features(c, "mintty", 0);
|
||||
else if (strncmp(tmp, "foot(", 5) == 0)
|
||||
tty_default_features(features, "foot", 0);
|
||||
tty_default_features(c, "foot", 0);
|
||||
else if (strncmp(tmp, "WezTerm ", 7) == 0)
|
||||
tty_default_features(features, "WezTerm", 0);
|
||||
tty_default_features(c, "WezTerm", 0);
|
||||
else if (strncmp(tmp, "ghostty ", 8) == 0)
|
||||
tty_default_features(features, "ghostty", 0);
|
||||
tty_default_features(c, "ghostty", 0);
|
||||
else if (strncmp(tmp, "Rio ", 4) == 0)
|
||||
tty_default_features(features, "Rio", 0);
|
||||
tty_default_features(c, "Rio", 0);
|
||||
log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf);
|
||||
|
||||
free(c->term_type);
|
||||
|
||||
21
tty-term.c
21
tty-term.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tty-term.c,v 1.107 2026/08/05 08:54:56 nicm Exp $ */
|
||||
/* $OpenBSD: tty-term.c,v 1.108 2026/08/17 14:47:41 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -544,8 +544,9 @@ tty_term_validate(struct tty_term *term)
|
||||
|
||||
struct tty_term *
|
||||
tty_term_create(struct tty *tty, char *name, char **caps, u_int ncaps,
|
||||
int *feat, char **cause)
|
||||
char **cause)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
struct tty_term *term;
|
||||
const struct tty_term_code_entry *ent;
|
||||
struct tty_code *code;
|
||||
@@ -617,7 +618,7 @@ tty_term_create(struct tty *tty, char *name, char **caps, u_int ncaps,
|
||||
offset = 0;
|
||||
first = tty_term_override_next(s, &offset);
|
||||
if (first != NULL && fnmatch(first, term->name, 0) == 0)
|
||||
tty_add_features(feat, s + offset, ":");
|
||||
tty_parse_client_features(c, s + offset, ":");
|
||||
a = options_array_next(a);
|
||||
}
|
||||
|
||||
@@ -627,14 +628,14 @@ tty_term_create(struct tty *tty, char *name, char **caps, u_int ncaps,
|
||||
del_curterm(cur_term);
|
||||
#endif
|
||||
/* Check for COLORTERM. */
|
||||
envent = environ_find(tty->client->environ, "COLORTERM");
|
||||
envent = environ_find(c->environ, "COLORTERM");
|
||||
if (envent != NULL) {
|
||||
log_debug("%s COLORTERM=%s", tty->client->name, envent->value);
|
||||
log_debug("%s COLORTERM=%s", c->name, envent->value);
|
||||
if (strcasecmp(envent->value, "truecolor") == 0 ||
|
||||
strcasecmp(envent->value, "24bit") == 0)
|
||||
tty_add_features(feat, "RGB", ",");
|
||||
tty_parse_client_features(c, "RGB", ",");
|
||||
else if (strstr(envent->value, "256") != NULL)
|
||||
tty_add_features(feat, "256", ",");
|
||||
tty_parse_client_features(c, "256", ",");
|
||||
}
|
||||
|
||||
/* Apply overrides so any capabilities used for features are changed. */
|
||||
@@ -665,17 +666,17 @@ tty_term_create(struct tty *tty, char *name, char **caps, u_int ncaps,
|
||||
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", ",");
|
||||
tty_parse_client_features(c, "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", ",");
|
||||
tty_parse_client_features(c, "RGB", ",");
|
||||
|
||||
/* Apply the features and overrides again. */
|
||||
if (tty_apply_features(term, *feat))
|
||||
if (tty_apply_features(term))
|
||||
tty_term_apply_overrides(term);
|
||||
|
||||
/* Log the capabilities. */
|
||||
|
||||
6
tty.c
6
tty.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tty.c,v 1.477 2026/07/17 12:42:51 nicm Exp $ */
|
||||
/* $OpenBSD: tty.c,v 1.478 2026/08/17 14:47:41 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -277,7 +277,7 @@ tty_open(struct tty *tty, char **cause)
|
||||
struct client *c = tty->client;
|
||||
|
||||
tty->term = tty_term_create(tty, c->term_name, c->term_caps,
|
||||
c->term_ncaps, &c->term_features, cause);
|
||||
c->term_ncaps, cause);
|
||||
if (tty->term == NULL) {
|
||||
tty_close(tty);
|
||||
return (-1);
|
||||
@@ -536,7 +536,7 @@ tty_update_features(struct tty *tty)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
|
||||
if (tty_apply_features(tty->term, c->term_features))
|
||||
if (tty_apply_features(tty->term))
|
||||
tty_term_apply_overrides(tty->term);
|
||||
|
||||
if (tty_use_margin(tty))
|
||||
|
||||
Reference in New Issue
Block a user