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.
pull/1016/merge
nicm 2017-07-26 16:14:08 +00:00
parent 3bb426d92c
commit 76887b1d27
4 changed files with 129 additions and 104 deletions

126
alerts.c
View File

@ -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);
}
}

View File

@ -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",

64
tmux.1
View File

@ -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

5
tmux.h
View File

@ -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