mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		
							
								
								
									
										248
									
								
								alerts.c
									
									
									
									
									
								
							
							
						
						
									
										248
									
								
								alerts.c
									
									
									
									
									
								
							@@ -19,6 +19,7 @@
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <event.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
@@ -29,13 +30,16 @@ static int	alerts_enabled(struct window *, int);
 | 
			
		||||
static void	alerts_callback(int, short, void *);
 | 
			
		||||
static void	alerts_reset(struct window *);
 | 
			
		||||
 | 
			
		||||
static void	alerts_run_hook(struct session *, struct winlink *, int);
 | 
			
		||||
static int	alerts_check_all(struct session *, struct winlink *);
 | 
			
		||||
static int	alerts_check_bell(struct session *, struct winlink *);
 | 
			
		||||
static int	alerts_check_activity(struct session *, struct winlink *);
 | 
			
		||||
static int	alerts_check_silence(struct session *, struct winlink *);
 | 
			
		||||
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 TAILQ_HEAD(, window) alerts_list = TAILQ_HEAD_INITIALIZER(alerts_list);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
alerts_timer(__unused int fd, __unused short events, void *arg)
 | 
			
		||||
{
 | 
			
		||||
@@ -49,53 +53,28 @@ alerts_timer(__unused int fd, __unused short events, void *arg)
 | 
			
		||||
static void
 | 
			
		||||
alerts_callback(__unused int fd, __unused short events, __unused void *arg)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w;
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
	int		 flags, alerts;
 | 
			
		||||
	struct window	*w, *w1;
 | 
			
		||||
	int		 alerts;
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH(w, windows, &windows) {
 | 
			
		||||
		RB_FOREACH(s, sessions, &sessions) {
 | 
			
		||||
			RB_FOREACH(wl, winlinks, &s->windows) {
 | 
			
		||||
				if (wl->window != w)
 | 
			
		||||
					continue;
 | 
			
		||||
				flags = w->flags;
 | 
			
		||||
	TAILQ_FOREACH_SAFE(w, &alerts_list, alerts_entry, w1) {
 | 
			
		||||
		alerts = alerts_check_all(w);
 | 
			
		||||
		log_debug("@%u alerts check, alerts %#x", w->id, alerts);
 | 
			
		||||
 | 
			
		||||
				alerts = alerts_check_all(s, wl);
 | 
			
		||||
 | 
			
		||||
				log_debug("%s:%d @%u alerts check, alerts %#x, "
 | 
			
		||||
				    "flags %#x", s->name, wl->idx, w->id,
 | 
			
		||||
				    alerts, flags);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		w->alerts_queued = 0;
 | 
			
		||||
		TAILQ_REMOVE(&alerts_list, w, alerts_entry);
 | 
			
		||||
		window_remove_ref(w);
 | 
			
		||||
	}
 | 
			
		||||
	alerts_fired = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
alerts_run_hook(struct session *s, struct winlink *wl, int flags)
 | 
			
		||||
{
 | 
			
		||||
	if (flags & WINDOW_BELL)
 | 
			
		||||
		notify_winlink("alert-bell", s, wl);
 | 
			
		||||
	if (flags & WINDOW_SILENCE)
 | 
			
		||||
		notify_winlink("alert-silence", s, wl);
 | 
			
		||||
	if (flags & WINDOW_ACTIVITY)
 | 
			
		||||
		notify_winlink("alert-activity", s, wl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
alerts_check_all(struct session *s, struct winlink *wl)
 | 
			
		||||
alerts_check_all(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	int	alerts;
 | 
			
		||||
 | 
			
		||||
	alerts  = alerts_check_bell(s, wl);
 | 
			
		||||
	alerts |= alerts_check_activity(s, wl);
 | 
			
		||||
	alerts |= alerts_check_silence(s, wl);
 | 
			
		||||
	if (alerts != 0) {
 | 
			
		||||
		alerts_run_hook(s, wl, alerts);
 | 
			
		||||
		server_status_session(s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	alerts  = alerts_check_bell(w);
 | 
			
		||||
	alerts |= alerts_check_activity(w);
 | 
			
		||||
	alerts |= alerts_check_silence(w);
 | 
			
		||||
	return (alerts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -105,7 +84,7 @@ alerts_check_session(struct session *s)
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH(wl, winlinks, &s->windows)
 | 
			
		||||
		alerts_check_all(s, wl);
 | 
			
		||||
		alerts_check_all(wl->window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
@@ -163,6 +142,12 @@ alerts_queue(struct window *w, int flags)
 | 
			
		||||
		log_debug("@%u alerts flags added %#x", w->id, flags);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!w->alerts_queued) {
 | 
			
		||||
		w->alerts_queued = 1;
 | 
			
		||||
		TAILQ_INSERT_TAIL(&alerts_list, w, alerts_entry);
 | 
			
		||||
		w->references++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!alerts_fired && alerts_enabled(w, flags)) {
 | 
			
		||||
		log_debug("alerts check queued (by @%u)", w->id);
 | 
			
		||||
		event_once(-1, EV_TIMEOUT, alerts_callback, NULL, NULL);
 | 
			
		||||
@@ -171,112 +156,157 @@ alerts_queue(struct window *w, int flags)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
alerts_check_bell(struct session *s, struct winlink *wl)
 | 
			
		||||
alerts_check_bell(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*ws;
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	struct window	*w = wl->window;
 | 
			
		||||
	int		 action, visual;
 | 
			
		||||
 | 
			
		||||
	if (!(w->flags & WINDOW_BELL))
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (s->curw != wl) {
 | 
			
		||||
		wl->flags |= WINLINK_BELL;
 | 
			
		||||
		w->flags &= ~WINDOW_BELL;
 | 
			
		||||
	}
 | 
			
		||||
	if (s->curw->window == w)
 | 
			
		||||
		w->flags &= ~WINDOW_BELL;
 | 
			
		||||
 | 
			
		||||
	action = options_get_number(s->options, "bell-action");
 | 
			
		||||
	if (action == BELL_NONE)
 | 
			
		||||
	if (~w->flags & WINDOW_BELL)
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	visual = options_get_number(s->options, "visual-bell");
 | 
			
		||||
	TAILQ_FOREACH(c, &clients, entry) {
 | 
			
		||||
		if (c->session != s || c->flags & CLIENT_CONTROL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!visual) {
 | 
			
		||||
			if ((action == BELL_CURRENT &&
 | 
			
		||||
			    c->session->curw->window == w) ||
 | 
			
		||||
			    (action == BELL_OTHER &&
 | 
			
		||||
			    c->session->curw->window != w) ||
 | 
			
		||||
			    action == BELL_ANY)
 | 
			
		||||
				tty_putcode(&c->tty, TTYC_BEL);
 | 
			
		||||
	TAILQ_FOREACH(wl, &w->winlinks, wentry)
 | 
			
		||||
		wl->session->flags &= ~SESSION_ALERTED;
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
 | 
			
		||||
		if (wl->flags & WINLINK_BELL)
 | 
			
		||||
			continue;
 | 
			
		||||
		s = wl->session;
 | 
			
		||||
		if (s->curw != wl) {
 | 
			
		||||
			wl->flags |= WINLINK_BELL;
 | 
			
		||||
			notify_winlink("alert-bell", s, wl);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (s->flags & SESSION_ALERTED)
 | 
			
		||||
			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);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (action == BELL_CURRENT && c->session->curw->window == w)
 | 
			
		||||
			status_message_set(c, "Bell in current window");
 | 
			
		||||
		else if (action == BELL_ANY || (action == BELL_OTHER &&
 | 
			
		||||
		    c->session->curw->window != w))
 | 
			
		||||
			status_message_set(c, "Bell in window %d", wl->idx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (WINDOW_BELL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
alerts_check_activity(struct session *s, struct winlink *wl)
 | 
			
		||||
alerts_check_activity(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	struct window	*w = wl->window;
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
 | 
			
		||||
	if (s->curw->window == w)
 | 
			
		||||
		w->flags &= ~WINDOW_ACTIVITY;
 | 
			
		||||
 | 
			
		||||
	if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_ACTIVITY)
 | 
			
		||||
	if (~w->flags & WINDOW_ACTIVITY)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (s->curw == wl)
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	if (!options_get_number(w->options, "monitor-activity"))
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	if (options_get_number(s->options, "bell-on-alert"))
 | 
			
		||||
		alerts_ring_bell(s);
 | 
			
		||||
	wl->flags |= WINLINK_ACTIVITY;
 | 
			
		||||
	TAILQ_FOREACH(wl, &w->winlinks, wentry)
 | 
			
		||||
		wl->session->flags &= ~SESSION_ALERTED;
 | 
			
		||||
 | 
			
		||||
	if (options_get_number(s->options, "visual-activity")) {
 | 
			
		||||
		TAILQ_FOREACH(c, &clients, entry) {
 | 
			
		||||
			if (c->session != s)
 | 
			
		||||
				continue;
 | 
			
		||||
			status_message_set(c, "Activity in window %d", wl->idx);
 | 
			
		||||
	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
 | 
			
		||||
		if (wl->flags & WINLINK_ACTIVITY)
 | 
			
		||||
			continue;
 | 
			
		||||
		s = wl->session;
 | 
			
		||||
		if (s->curw != wl) {
 | 
			
		||||
			wl->flags |= WINLINK_ACTIVITY;
 | 
			
		||||
			notify_winlink("alert-activity", s, 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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (WINDOW_ACTIVITY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
alerts_check_silence(struct session *s, struct winlink *wl)
 | 
			
		||||
alerts_check_silence(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	struct window	*w = wl->window;
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
 | 
			
		||||
	if (s->curw->window == w)
 | 
			
		||||
		w->flags &= ~WINDOW_SILENCE;
 | 
			
		||||
 | 
			
		||||
	if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE)
 | 
			
		||||
	if (~w->flags & WINDOW_SILENCE)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (s->curw == wl)
 | 
			
		||||
	if (!options_get_number(w->options, "monitor-silence"))
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	if (options_get_number(w->options, "monitor-silence") == 0)
 | 
			
		||||
		return (0);
 | 
			
		||||
	TAILQ_FOREACH(wl, &w->winlinks, wentry)
 | 
			
		||||
		wl->session->flags &= ~SESSION_ALERTED;
 | 
			
		||||
 | 
			
		||||
	if (options_get_number(s->options, "bell-on-alert"))
 | 
			
		||||
		alerts_ring_bell(s);
 | 
			
		||||
	wl->flags |= WINLINK_SILENCE;
 | 
			
		||||
 | 
			
		||||
	if (options_get_number(s->options, "visual-silence")) {
 | 
			
		||||
		TAILQ_FOREACH(c, &clients, entry) {
 | 
			
		||||
			if (c->session != s)
 | 
			
		||||
				continue;
 | 
			
		||||
			status_message_set(c, "Silence in window %d", wl->idx);
 | 
			
		||||
	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
 | 
			
		||||
		if (wl->flags & WINLINK_SILENCE)
 | 
			
		||||
			continue;
 | 
			
		||||
		s = wl->session;
 | 
			
		||||
		if (s->curw != wl) {
 | 
			
		||||
			wl->flags |= WINLINK_SILENCE;
 | 
			
		||||
			notify_winlink("alert-silence", s, 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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (WINDOW_SILENCE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
alerts_set_message(struct session *s, const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	va_list		 ap;
 | 
			
		||||
	char		*message;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, fmt);
 | 
			
		||||
	xvasprintf(&message, fmt, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(c, &clients, entry) {
 | 
			
		||||
		if (c->session == s)
 | 
			
		||||
			status_message_set(c, "%s", message);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free(message);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
alerts_ring_bell(struct session *s)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -296,7 +296,6 @@ key_bindings_init(void)
 | 
			
		||||
		"bind -Tcopy-mode C-Up send -X scroll-up",
 | 
			
		||||
		"bind -Tcopy-mode C-Down send -X scroll-down",
 | 
			
		||||
 | 
			
		||||
		"bind -Tcopy-mode-vi C-b send -X page-up",
 | 
			
		||||
		"bind -Tcopy-mode-vi C-c send -X cancel",
 | 
			
		||||
		"bind -Tcopy-mode-vi C-d send -X halfpage-down",
 | 
			
		||||
		"bind -Tcopy-mode-vi C-e send -X scroll-down",
 | 
			
		||||
 
 | 
			
		||||
@@ -851,6 +851,7 @@ server_client_loop(void)
 | 
			
		||||
	struct client		*c;
 | 
			
		||||
	struct window		*w;
 | 
			
		||||
	struct window_pane	*wp;
 | 
			
		||||
	int			 focus;
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(c, &clients, entry) {
 | 
			
		||||
		server_client_check_exit(c);
 | 
			
		||||
@@ -864,11 +865,13 @@ server_client_loop(void)
 | 
			
		||||
	 * Any windows will have been redrawn as part of clients, so clear
 | 
			
		||||
	 * their flags now. Also check pane focus and resize.
 | 
			
		||||
	 */
 | 
			
		||||
	focus = options_get_number(global_options, "focus-events");
 | 
			
		||||
	RB_FOREACH(w, windows, &windows) {
 | 
			
		||||
		w->flags &= ~WINDOW_REDRAW;
 | 
			
		||||
		TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
			
		||||
			if (wp->fd != -1) {
 | 
			
		||||
				server_client_check_focus(wp);
 | 
			
		||||
				if (focus)
 | 
			
		||||
					server_client_check_focus(wp);
 | 
			
		||||
				server_client_check_resize(wp);
 | 
			
		||||
			}
 | 
			
		||||
			wp->flags &= ~PANE_REDRAW;
 | 
			
		||||
@@ -945,10 +948,6 @@ server_client_check_focus(struct window_pane *wp)
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	int		 push;
 | 
			
		||||
 | 
			
		||||
	/* Are focus events off? */
 | 
			
		||||
	if (!options_get_number(global_options, "focus-events"))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* Do we need to push the focus state? */
 | 
			
		||||
	push = wp->flags & PANE_FOCUSPUSH;
 | 
			
		||||
	wp->flags &= ~PANE_FOCUSPUSH;
 | 
			
		||||
 
 | 
			
		||||
@@ -336,6 +336,7 @@ session_new(struct session *s, const char *name, int argc, char **argv,
 | 
			
		||||
		xasprintf(cause, "index in use: %d", idx);
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
	wl->session = s;
 | 
			
		||||
 | 
			
		||||
	env = environ_create();
 | 
			
		||||
	environ_copy(global_environ, env);
 | 
			
		||||
@@ -372,6 +373,7 @@ session_attach(struct session *s, struct window *w, int idx, char **cause)
 | 
			
		||||
		xasprintf(cause, "index in use: %d", idx);
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
	wl->session = s;
 | 
			
		||||
	winlink_set_window(wl, w);
 | 
			
		||||
	notify_session_window("window-linked", s, w);
 | 
			
		||||
 | 
			
		||||
@@ -408,8 +410,8 @@ session_has(struct session *s, struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH(wl, winlinks, &s->windows) {
 | 
			
		||||
		if (wl->window == w)
 | 
			
		||||
	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
 | 
			
		||||
		if (wl->session == s)
 | 
			
		||||
			return (1);
 | 
			
		||||
	}
 | 
			
		||||
	return (0);
 | 
			
		||||
@@ -678,6 +680,7 @@ session_group_synchronize1(struct session *target, struct session *s)
 | 
			
		||||
	/* Link all the windows from the target. */
 | 
			
		||||
	RB_FOREACH(wl, winlinks, ww) {
 | 
			
		||||
		wl2 = winlink_add(&s->windows, wl->idx);
 | 
			
		||||
		wl2->session = s;
 | 
			
		||||
		winlink_set_window(wl2, wl->window);
 | 
			
		||||
		notify_session_window("window-linked", s, wl2->window);
 | 
			
		||||
		wl2->flags |= wl->flags & WINLINK_ALERTFLAGS;
 | 
			
		||||
@@ -728,6 +731,7 @@ session_renumber_windows(struct session *s)
 | 
			
		||||
	/* Go through the winlinks and assign new indexes. */
 | 
			
		||||
	RB_FOREACH(wl, winlinks, &old_wins) {
 | 
			
		||||
		wl_new = winlink_add(&s->windows, new_idx);
 | 
			
		||||
		wl_new->session = s;
 | 
			
		||||
		winlink_set_window(wl_new, wl->window);
 | 
			
		||||
		wl_new->flags |= wl->flags & WINLINK_ALERTFLAGS;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								tmux.h
									
									
									
									
									
								
							@@ -891,12 +891,16 @@ struct window {
 | 
			
		||||
#define WINDOW_STYLECHANGED 0x8000
 | 
			
		||||
#define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE)
 | 
			
		||||
 | 
			
		||||
	int		 alerts_queued;
 | 
			
		||||
	TAILQ_ENTRY(window) alerts_entry;
 | 
			
		||||
 | 
			
		||||
	struct options	*options;
 | 
			
		||||
 | 
			
		||||
	struct grid_cell style;
 | 
			
		||||
	struct grid_cell active_style;
 | 
			
		||||
 | 
			
		||||
	u_int		 references;
 | 
			
		||||
	TAILQ_HEAD(, winlink) winlinks;
 | 
			
		||||
 | 
			
		||||
	RB_ENTRY(window) entry;
 | 
			
		||||
};
 | 
			
		||||
@@ -905,6 +909,7 @@ RB_HEAD(windows, window);
 | 
			
		||||
/* Entry on local window list. */
 | 
			
		||||
struct winlink {
 | 
			
		||||
	int		 idx;
 | 
			
		||||
	struct session	*session;
 | 
			
		||||
	struct window	*window;
 | 
			
		||||
 | 
			
		||||
	size_t		 status_width;
 | 
			
		||||
@@ -918,6 +923,7 @@ struct winlink {
 | 
			
		||||
#define WINLINK_ALERTFLAGS (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_SILENCE)
 | 
			
		||||
 | 
			
		||||
	RB_ENTRY(winlink) entry;
 | 
			
		||||
	TAILQ_ENTRY(winlink) wentry;
 | 
			
		||||
	TAILQ_ENTRY(winlink) sentry;
 | 
			
		||||
};
 | 
			
		||||
RB_HEAD(winlinks, winlink);
 | 
			
		||||
@@ -992,6 +998,7 @@ struct session {
 | 
			
		||||
 | 
			
		||||
#define SESSION_UNATTACHED 0x1	/* not attached to any clients */
 | 
			
		||||
#define SESSION_PASTING 0x2
 | 
			
		||||
#define SESSION_ALERTED 0x4
 | 
			
		||||
	int		 flags;
 | 
			
		||||
 | 
			
		||||
	u_int		 attached;
 | 
			
		||||
@@ -2071,7 +2078,6 @@ struct window	*window_create(u_int, u_int);
 | 
			
		||||
struct window	*window_create_spawn(const char *, int, char **, const char *,
 | 
			
		||||
		     const char *, const char *, struct environ *,
 | 
			
		||||
		     struct termios *, u_int, u_int, u_int, char **);
 | 
			
		||||
void		 window_destroy(struct window *);
 | 
			
		||||
struct window_pane *window_get_active_at(struct window *, u_int, u_int);
 | 
			
		||||
struct window_pane *window_find_string(struct window *, const char *);
 | 
			
		||||
int		 window_has_pane(struct window *, struct window_pane *);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								window.c
									
									
									
									
									
								
							@@ -60,6 +60,8 @@ static u_int	next_window_pane_id;
 | 
			
		||||
static u_int	next_window_id;
 | 
			
		||||
static u_int	next_active_point;
 | 
			
		||||
 | 
			
		||||
static void	window_destroy(struct window *);
 | 
			
		||||
 | 
			
		||||
static struct window_pane *window_pane_create(struct window *, u_int, u_int,
 | 
			
		||||
		    u_int);
 | 
			
		||||
static void	window_pane_destroy(struct window_pane *);
 | 
			
		||||
@@ -184,6 +186,11 @@ winlink_add(struct winlinks *wwl, int idx)
 | 
			
		||||
void
 | 
			
		||||
winlink_set_window(struct winlink *wl, struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	if (wl->window != NULL) {
 | 
			
		||||
		TAILQ_REMOVE(&wl->window->winlinks, wl, wentry);
 | 
			
		||||
		window_remove_ref(w);
 | 
			
		||||
	}
 | 
			
		||||
	TAILQ_INSERT_TAIL(&w->winlinks, wl, wentry);
 | 
			
		||||
	wl->window = w;
 | 
			
		||||
	w->references++;
 | 
			
		||||
}
 | 
			
		||||
@@ -193,12 +200,14 @@ winlink_remove(struct winlinks *wwl, struct winlink *wl)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w = wl->window;
 | 
			
		||||
 | 
			
		||||
	if (w != NULL) {
 | 
			
		||||
		TAILQ_REMOVE(&w->winlinks, wl, wentry);
 | 
			
		||||
		window_remove_ref(w);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RB_REMOVE(winlinks, wwl, wl);
 | 
			
		||||
	free(wl->status_text);
 | 
			
		||||
	free(wl);
 | 
			
		||||
 | 
			
		||||
	if (w != NULL)
 | 
			
		||||
		window_remove_ref(w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct winlink *
 | 
			
		||||
@@ -313,6 +322,7 @@ window_create(u_int sx, u_int sy)
 | 
			
		||||
	w->options = options_create(global_w_options);
 | 
			
		||||
 | 
			
		||||
	w->references = 0;
 | 
			
		||||
	TAILQ_INIT(&w->winlinks);
 | 
			
		||||
 | 
			
		||||
	w->id = next_window_id++;
 | 
			
		||||
	RB_INSERT(windows, &windows, w);
 | 
			
		||||
@@ -350,9 +360,12 @@ window_create_spawn(const char *name, int argc, char **argv, const char *path,
 | 
			
		||||
	return (w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
window_destroy(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	if (!TAILQ_EMPTY(&w->winlinks))
 | 
			
		||||
		fatalx("window destroyed with winlinks");
 | 
			
		||||
 | 
			
		||||
	RB_REMOVE(windows, &windows, w);
 | 
			
		||||
 | 
			
		||||
	if (w->layout_root != NULL)
 | 
			
		||||
@@ -1436,19 +1449,13 @@ window_pane_find_right(struct window_pane *wp)
 | 
			
		||||
void
 | 
			
		||||
winlink_clear_flags(struct winlink *wl)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	struct winlink	*wl_loop;
 | 
			
		||||
	struct winlink	*loop;
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH(s, sessions, &sessions) {
 | 
			
		||||
		RB_FOREACH(wl_loop, winlinks, &s->windows) {
 | 
			
		||||
			if (wl_loop->window != wl->window)
 | 
			
		||||
				continue;
 | 
			
		||||
			if ((wl_loop->flags & WINLINK_ALERTFLAGS) == 0)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			wl_loop->flags &= ~WINLINK_ALERTFLAGS;
 | 
			
		||||
			wl_loop->window->flags &= ~WINDOW_ALERTFLAGS;
 | 
			
		||||
			server_status_session(s);
 | 
			
		||||
	wl->window->flags &= ~WINDOW_ALERTFLAGS;
 | 
			
		||||
	TAILQ_FOREACH(loop, &wl->window->winlinks, wentry) {
 | 
			
		||||
		if ((loop->flags & WINLINK_ALERTFLAGS) != 0) {
 | 
			
		||||
			loop->flags &= ~WINLINK_ALERTFLAGS;
 | 
			
		||||
			server_status_session(loop->session);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user