mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Add an option to alert (monitor) for silence (lack of activity) in a
window. From Thomas Adam.
This commit is contained in:
		@@ -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))
 | 
			
		||||
 
 | 
			
		||||
@@ -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 },
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
@@ -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(
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								tmux.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								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 */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user