summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd-choose-window.c2
-rw-r--r--cmd-set-option.c2
-rw-r--r--input.c2
-rw-r--r--server-window.c53
-rw-r--r--status.c2
-rw-r--r--tmux.117
-rw-r--r--tmux.c2
-rw-r--r--tmux.h6
-rw-r--r--window.c8
9 files changed, 92 insertions, 2 deletions
diff --git a/cmd-choose-window.c b/cmd-choose-window.c
index e341dd41..b3e4b2b3 100644
--- a/cmd-choose-window.c
+++ b/cmd-choose-window.c
@@ -87,6 +87,8 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
flag = '!';
else if (wm->flags & WINLINK_CONTENT)
flag = '+';
+ else if (wm->flags & WINLINK_SILENCE)
+ flag = '~';
else if (wm == s->curw)
flag = '*';
else if (wm == TAILQ_FIRST(&s->lastw))
diff --git a/cmd-set-option.c b/cmd-set-option.c
index 684f1b04..7856a52e 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -136,6 +136,7 @@ const struct set_option_entry set_session_option_table[] = {
{ "visual-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-bell", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-content", SET_OPTION_FLAG, 0, 0, NULL },
+ { "visual-silence", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
@@ -157,6 +158,7 @@ const struct set_option_entry set_window_option_table[] = {
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
+ { "monitor-silence",SET_OPTION_NUMBER, 0, INT_MAX, NULL},
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "synchronize-panes", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
diff --git a/input.c b/input.c
index f49591a7..4a964550 100644
--- a/input.c
+++ b/input.c
@@ -681,7 +681,9 @@ input_parse(struct window_pane *wp)
if (EVBUFFER_LENGTH(evb) == 0)
return;
+
wp->window->flags |= WINDOW_ACTIVITY;
+ wp->window->flags &= ~WINDOW_SILENCE;
/*
* Open the screen. Use NULL wp if there is a mode set as don't want to
diff --git a/server-window.c b/server-window.c
index 634a1b8a..abf82499 100644
--- a/server-window.c
+++ b/server-window.c
@@ -26,6 +26,7 @@
int server_window_backoff(struct window_pane *);
int server_window_check_bell(struct session *, struct winlink *);
int server_window_check_activity(struct session *, struct winlink *);
+int server_window_check_silence(struct session *, struct winlink *);
int server_window_check_content(
struct session *, struct winlink *, struct window_pane *);
@@ -53,7 +54,8 @@ server_window_loop(void)
continue;
if (server_window_check_bell(s, wl) ||
- server_window_check_activity(s, wl))
+ server_window_check_activity(s, wl) ||
+ server_window_check_silence(s, wl))
server_status_session(s);
TAILQ_FOREACH(wp, &w->panes, entry)
server_window_check_content(s, wl, wp);
@@ -151,6 +153,55 @@ server_window_check_activity(struct session *s, struct winlink *wl)
return (1);
}
+/* Check for silence in window. */
+int
+server_window_check_silence(struct session *s, struct winlink *wl)
+{
+ struct client *c;
+ struct window *w = wl->window;
+ struct timeval timer;
+ u_int i;
+ int silence_interval, timer_difference;
+
+ if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE)
+ return (0);
+
+ if (s->curw == wl) {
+ /*
+ * Reset the timer for this window if we've focused it. We
+ * don't want the timer tripping as soon as we've switched away
+ * from this window.
+ */
+ if (gettimeofday(&w->silence_timer, NULL) != 0)
+ fatal("gettimeofday failed.");
+
+ return (0);
+ }
+
+ silence_interval = options_get_number(&w->options, "monitor-silence");
+ if (silence_interval == 0)
+ return (0);
+
+ if (gettimeofday(&timer, NULL) != 0)
+ fatal("gettimeofday");
+ timer_difference = timer.tv_sec - w->silence_timer.tv_sec;
+ if (timer_difference <= silence_interval)
+ return (0);
+ wl->flags |= WINLINK_SILENCE;
+
+ if (options_get_number(&s->options, "visual-silence")) {
+ for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
+ c = ARRAY_ITEM(&clients, i);
+ if (c == NULL || c->session != s)
+ continue;
+ status_message_set(c, "Silence in window %u",
+ winlink_find_by_window(&s->windows, w)->idx);
+ }
+ }
+
+ return (1);
+}
+
/* Check for content change in window. */
int
server_window_check_content(
diff --git a/status.c b/status.c
index b1d93c97..65a0afeb 100644
--- a/status.c
+++ b/status.c
@@ -395,6 +395,8 @@ status_replace1(struct client *c,struct winlink *wl,
tmp[0] = '!';
else if (wl->flags & WINLINK_ACTIVITY)
tmp[0] = '#';
+ else if (wl->flags & WINLINK_SILENCE)
+ tmp[0] = '~';
else if (wl == s->curw)
tmp[0] = '*';
else if (wl == TAILQ_FIRST(&s->lastw))
diff --git a/tmux.1 b/tmux.1
index de5144a5..8ce1cce9 100644
--- a/tmux.1
+++ b/tmux.1
@@ -2053,6 +2053,12 @@ display a message when content is present in a window
for which the
.Ic monitor-content
window option is enabled.
+.It Xo Ic visual-silence
+.Op Ic on | off
+.Xc
+If
+.Ic monitor-silence
+is enabled, prints a message after the interval has expired on a given window.
.El
.It Xo Ic set-window-option
.Op Fl agu
@@ -2175,6 +2181,16 @@ pattern
.Ar match-string
appears in the window, it is highlighted in the status line.
.Pp
+.It Xo Ic monitor-silence
+.Op Ic interval
+.Xc
+Monitor for silence (no activity) in the window within
+.Ic interval
+seconds.
+Windows that have been silent for the interval are highlighted in the
+status line.
+An interval of zero disables the monitoring.
+.Pp
.It Xo Ic remain-on-exit
.Op Ic on | off
.Xc
@@ -2386,6 +2402,7 @@ The flag is one of the following symbols appended to the window name:
.It Li "#" Ta "Window is monitored and activity has been detected."
.It Li "!" Ta "A bell has occurred in the window."
.It Li "+" Ta "Window is monitored for content and it has appeared."
+.It Li "~" Ta "The window has been silent for the monitor-silence interval."
.El
.Pp
The # symbol relates to the
diff --git a/tmux.c b/tmux.c
index c5793955..0ebeea28 100644
--- a/tmux.c
+++ b/tmux.c
@@ -379,6 +379,7 @@ main(int argc, char **argv)
options_set_number(so, "visual-activity", 0);
options_set_number(so, "visual-bell", 0);
options_set_number(so, "visual-content", 0);
+ options_set_number(so, "visual-silence", 0);
keylist = xmalloc(sizeof *keylist);
ARRAY_INIT(keylist);
@@ -402,6 +403,7 @@ main(int argc, char **argv)
options_set_number(wo, "mode-mouse", 0);
options_set_number(wo, "monitor-activity", 0);
options_set_string(wo, "monitor-content", "%s", "");
+ options_set_number(wo, "monitor-silence", 0);
options_set_number(wo, "window-status-attr", 0);
options_set_number(wo, "window-status-bg", 8);
options_set_number(wo, "window-status-current-attr", 0);
diff --git a/tmux.h b/tmux.h
index e4323a5d..529b6439 100644
--- a/tmux.h
+++ b/tmux.h
@@ -830,6 +830,7 @@ TAILQ_HEAD(window_panes, window_pane);
struct window {
char *name;
struct event name_timer;
+ struct timeval silence_timer;
struct window_pane *active;
struct window_pane *last;
@@ -845,6 +846,7 @@ struct window {
#define WINDOW_BELL 0x1
#define WINDOW_ACTIVITY 0x2
#define WINDOW_REDRAW 0x4
+#define WINDOW_SILENCE 0x8
struct options options;
@@ -865,7 +867,9 @@ struct winlink {
#define WINLINK_BELL 0x1
#define WINLINK_ACTIVITY 0x2
#define WINLINK_CONTENT 0x4
-#define WINLINK_ALERTFLAGS (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_CONTENT)
+#define WINLINK_SILENCE 0x8
+#define WINLINK_ALERTFLAGS \
+ (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_CONTENT|WINLINK_SILENCE)
RB_ENTRY(winlink) entry;
TAILQ_ENTRY(winlink) sentry;
diff --git a/window.c b/window.c
index a7a5c40e..95877cb5 100644
--- a/window.c
+++ b/window.c
@@ -639,6 +639,14 @@ window_pane_read_callback(unused struct bufferevent *bufev, void *data)
input_parse(wp);
wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);
+
+ /*
+ * If we get here, we're not outputting anymore, so set the silence
+ * flag on the window.
+ */
+ wp->window->flags |= WINDOW_SILENCE;
+ if (gettimeofday(&wp->window->silence_timer, NULL) != 0)
+ fatal("gettimeofday failed.");
}
/* ARGSUSED */