From 76887b1d27386b5418f953064d7e47389a6831be Mon Sep 17 00:00:00 2001 From: nicm <nicm> Date: Wed, 26 Jul 2017 16:14:08 +0000 Subject: [PATCH] Make bell, activity and silence alerting more consistent: - remove the bell-on-alert option; - add activity-action and silence-action options with the same possible values as the existing bell-action; - add "both" value for the visual-bell, visual-activity and visual-silence options to trigger both a bell and a message. This means all three work the same way. Based on changes from Yvain Thonnart. --- alerts.c | 126 +++++++++++++++++++++--------------------------- options-table.c | 38 ++++++++++----- tmux.1 | 64 +++++++++++++++--------- tmux.h | 5 ++ 4 files changed, 129 insertions(+), 104 deletions(-) diff --git a/alerts.c b/alerts.c index a489d444..afeafb44 100644 --- a/alerts.c +++ b/alerts.c @@ -34,9 +34,8 @@ static int alerts_check_all(struct window *); static int alerts_check_bell(struct window *); static int alerts_check_activity(struct window *); static int alerts_check_silence(struct window *); -static void printflike(2, 3) alerts_set_message(struct session *, const char *, - ...); -static void alerts_ring_bell(struct session *); +static void alerts_set_message(struct session *, struct window *, + struct winlink *, const char *, int, int); static TAILQ_HEAD(, window) alerts_list = TAILQ_HEAD_INITIALIZER(alerts_list); @@ -162,11 +161,8 @@ alerts_queue(struct window *w, int flags) static int alerts_check_bell(struct window *w) { - struct window *ws; struct winlink *wl; struct session *s; - struct client *c; - int action, visual; if (~w->flags & WINDOW_BELL) return (0); @@ -187,33 +183,9 @@ alerts_check_bell(struct window *w) continue; s->flags |= SESSION_ALERTED; - action = options_get_number(s->options, "bell-action"); - if (action == BELL_NONE) - return (0); - - visual = options_get_number(s->options, "visual-bell"); - TAILQ_FOREACH(c, &clients, entry) { - if (c->session != s || c->flags & CLIENT_CONTROL) - continue; - ws = c->session->curw->window; - - if (action == BELL_CURRENT && ws != w) - action = BELL_NONE; - if (action == BELL_OTHER && ws != w) - action = BELL_NONE; - - if (!visual) { - if (action != BELL_NONE) - tty_putcode(&c->tty, TTYC_BEL); - continue; - } - if (action == BELL_CURRENT) - status_message_set(c, "Bell in current window"); - else if (action != BELL_NONE) { - status_message_set(c, "Bell in window %d", - wl->idx); - } - } + alerts_set_message(s, w, wl, "Bell", + options_get_number(s->options, "bell-action"), + options_get_number(s->options, "visual-bell")); } return (WINDOW_BELL); @@ -237,20 +209,18 @@ alerts_check_activity(struct window *w) if (wl->flags & WINLINK_ACTIVITY) continue; s = wl->session; - if (s->curw == wl) - continue; - - wl->flags |= WINLINK_ACTIVITY; - notify_winlink("alert-activity", wl); + if (s->curw != wl) { + wl->flags |= WINLINK_ACTIVITY; + notify_winlink("alert-activity", wl); + } if (s->flags & SESSION_ALERTED) continue; s->flags |= SESSION_ALERTED; - if (options_get_number(s->options, "bell-on-alert")) - alerts_ring_bell(s); - if (options_get_number(s->options, "visual-activity")) - alerts_set_message(s, "Activity in window %d", wl->idx); + alerts_set_message(s, w, wl, "Activity", + options_get_number(s->options, "activity-action"), + options_get_number(s->options, "visual-activity")); } return (WINDOW_ACTIVITY); @@ -264,7 +234,7 @@ alerts_check_silence(struct window *w) if (~w->flags & WINDOW_SILENCE) return (0); - if (!options_get_number(w->options, "monitor-silence")) + if (options_get_number(w->options, "monitor-silence") == 0) return (0); TAILQ_FOREACH(wl, &w->winlinks, wentry) @@ -274,50 +244,66 @@ alerts_check_silence(struct window *w) if (wl->flags & WINLINK_SILENCE) continue; s = wl->session; - if (s->curw == wl) - continue; - wl->flags |= WINLINK_SILENCE; - notify_winlink("alert-silence", wl); + if (s->curw != wl) { + wl->flags |= WINLINK_SILENCE; + notify_winlink("alert-silence", wl); + } if (s->flags & SESSION_ALERTED) continue; s->flags |= SESSION_ALERTED; - if (options_get_number(s->options, "bell-on-alert")) - alerts_ring_bell(s); - if (options_get_number(s->options, "visual-silence")) - alerts_set_message(s, "Silence in window %d", wl->idx); + alerts_set_message(s, w, wl, "Silence", + options_get_number(s->options, "silence-action"), + options_get_number(s->options, "visual-silence")); } return (WINDOW_SILENCE); } static void -alerts_set_message(struct session *s, const char *fmt, ...) +alerts_set_message(struct session *s, struct window *w, struct winlink *wl, + const char *type, int action, int visual) { struct client *c; - va_list ap; - char *message; + int flag; - va_start(ap, fmt); - xvasprintf(&message, fmt, ap); - va_end(ap); + /* + * We have found an alert (bell, activity or silence), so we need + * to notify the user. For each client attached to this session, + * decide whether a bell (or visual message) is needed. + * + * {bell,activity,silence}-action determines when we notify: none means + * nothing happens, current means we only do something for the current + * window and other means only for windows other than the current. + * + * If visual-{bell,activity,silence} is on, then a message is + * substituted for a bell; if it is off, a bell is sent as normal; both + * mean both a bell and visual message is sent. + */ + if (action == BELL_NONE) + return; TAILQ_FOREACH(c, &clients, entry) { - if (c->session == s) - status_message_set(c, "%s", message); - } + if (c->session != s || c->flags & CLIENT_CONTROL) + continue; + flag = 0; + if (action == BELL_ANY) + flag = 1; + else if (action == BELL_CURRENT) + flag = (c->session->curw->window == w); + else if (action == BELL_OTHER) + flag = (c->session->curw->window != w); + if (!flag) + continue; - free(message); -} - -static void -alerts_ring_bell(struct session *s) -{ - struct client *c; - - TAILQ_FOREACH(c, &clients, entry) { - if (c->session == s && !(c->flags & CLIENT_CONTROL)) + if (visual == VISUAL_OFF || visual == VISUAL_BOTH) tty_putcode(&c->tty, TTYC_BEL); + if (visual == VISUAL_OFF) + continue; + if (c->session->curw->window == w) + status_message_set(c, "%s in current window", type); + else + status_message_set(c, "%s in window %d", type, wl->idx); } } diff --git a/options-table.c b/options-table.c index 91075871..7ad1c2f6 100644 --- a/options-table.c +++ b/options-table.c @@ -51,6 +51,9 @@ static const char *options_table_status_position_list[] = { static const char *options_table_bell_action_list[] = { "none", "any", "current", "other", NULL }; +static const char *options_table_visual_bell_list[] = { + "off", "on", "both", NULL +}; static const char *options_table_pane_status_list[] = { "off", "top", "bottom", NULL }; @@ -143,6 +146,13 @@ const struct options_table_entry options_table[] = { .separator = "," }, + { .name = "activity-action", + .type = OPTIONS_TABLE_CHOICE, + .scope = OPTIONS_TABLE_SESSION, + .choices = options_table_bell_action_list, + .default_num = BELL_OTHER + }, + { .name = "assume-paste-time", .type = OPTIONS_TABLE_NUMBER, .scope = OPTIONS_TABLE_SESSION, @@ -166,12 +176,6 @@ const struct options_table_entry options_table[] = { .default_num = BELL_ANY }, - { .name = "bell-on-alert", - .type = OPTIONS_TABLE_FLAG, - .scope = OPTIONS_TABLE_SESSION, - .default_num = 0 - }, - { .name = "default-command", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SESSION, @@ -350,6 +354,13 @@ const struct options_table_entry options_table[] = { .default_str = "#S:#I:#W - \"#T\" #{session_alerts}" }, + { .name = "silence-action", + .type = OPTIONS_TABLE_CHOICE, + .scope = OPTIONS_TABLE_SESSION, + .choices = options_table_bell_action_list, + .default_num = BELL_OTHER + }, + { .name = "status", .type = OPTIONS_TABLE_FLAG, .scope = OPTIONS_TABLE_SESSION, @@ -502,21 +513,24 @@ const struct options_table_entry options_table[] = { }, { .name = "visual-activity", - .type = OPTIONS_TABLE_FLAG, + .type = OPTIONS_TABLE_CHOICE, .scope = OPTIONS_TABLE_SESSION, - .default_num = 0 + .choices = options_table_visual_bell_list, + .default_num = VISUAL_OFF }, { .name = "visual-bell", - .type = OPTIONS_TABLE_FLAG, + .type = OPTIONS_TABLE_CHOICE, .scope = OPTIONS_TABLE_SESSION, - .default_num = 0 + .choices = options_table_visual_bell_list, + .default_num = VISUAL_OFF }, { .name = "visual-silence", - .type = OPTIONS_TABLE_FLAG, + .type = OPTIONS_TABLE_CHOICE, .scope = OPTIONS_TABLE_SESSION, - .default_num = 0 + .choices = options_table_visual_bell_list, + .default_num = VISUAL_OFF }, { .name = "word-separators", diff --git a/tmux.1 b/tmux.1 index c9a181e6..fc9f3ec7 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2515,6 +2515,25 @@ before interpretation. .Pp Available session options are: .Bl -tag -width Ds +.It Xo Ic activity-action +.Op Ic any | none | current | other +.Xc +Set action on window activity when +.Ic monitor-activity +is on. +.Ic any +means activity in any window linked to a session causes a bell or message +(depending on +.Ic visual-activity ) +in the current window of that session, +.Ic none +means all activity is ignored (equivalent to +.Ic monitor-activity +being off), +.Ic current +means only activity in windows other than the current window are ignored and +.Ic other +means activity in the current window is ignored but not those in other windows. .It Ic assume-paste-time Ar milliseconds If keys are entered faster than one in .Ar milliseconds , @@ -2530,20 +2549,8 @@ The default is zero. .Op Ic any | none | current | other .Xc Set action on window bell. -.Ic any -means a bell in any window linked to a session causes a bell in the current -window of that session, -.Ic none -means all bells are ignored, -.Ic current -means only bells in windows other than the current window are ignored and -.Ic other -means bells in the current window are ignored but not those in other windows. -.It Xo Ic bell-on-alert -.Op Ic on | off -.Xc -If on, ring the terminal bell when an alert -occurs. +The values are the same as those for +.Ic activity-action . .It Ic default-command Ar shell-command Set the command used for new windows (if not specified when the window is created) to @@ -2759,6 +2766,15 @@ is on. Formats are expanded, see the .Sx FORMATS section. +.It Xo Ic silence-action +.Op Ic any | none | current | other +.Xc +Set action on window silence when +.Ic monitor-silence +is on. +The values are the same as those for +.Ic activity-action . +.Pp .It Xo Ic status .Op Ic on | off .Xc @@ -2884,26 +2900,30 @@ set -s user-keys[0] '\e[5;30012~' bind User0 resize-pane -L 3 .Ed .It Xo Ic visual-activity -.Op Ic on | off +.Op Ic on | off | both .Xc -If on, display a status line message when activity occurs in a window -for which the +If on, display a message instead of sending a bell when activity occurs in a +window for which the .Ic monitor-activity window option is enabled. +If set to both, a bell and a message are produced. .It Xo Ic visual-bell -.Op Ic on | off +.Op Ic on | off | both .Xc -If this option is on, a message is shown on a bell instead of it being passed -through to the terminal (which normally makes a sound). +If on, a message is shown on a bell instead of it being passed through to the +terminal (which normally makes a sound). +If set to both, a bell and a message are produced. Also see the .Ic bell-action option. .It Xo Ic visual-silence -.Op Ic on | off +.Op Ic on | off | both .Xc If .Ic monitor-silence -is enabled, prints a message after the interval has expired on a given window. +is enabled, prints a message after the interval has expired on a given window +instead of sending a bell. +If set to both, a bell and a message are produced. .It Ic word-separators Ar string Sets the session's conception of what characters are considered word separators, for the purposes of the next and previous word commands in diff --git a/tmux.h b/tmux.h index 855a1dff..d8959571 100644 --- a/tmux.h +++ b/tmux.h @@ -83,6 +83,11 @@ struct tmuxproc; #define BELL_CURRENT 2 #define BELL_OTHER 3 +/* Visual option values. */ +#define VISUAL_OFF 0 +#define VISUAL_ON 1 +#define VISUAL_BOTH 2 + /* Special key codes. */ #define KEYC_NONE 0xffff00000000ULL #define KEYC_UNKNOWN 0xfffe00000000ULL