mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Having a list of winlinks->alerts for each session is stupid, just store
the alert flags directly in the winlink itself.
This commit is contained in:
		
							
								
								
									
										125
									
								
								session.c
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								session.c
									
									
									
									
									
								
							@@ -32,71 +32,8 @@ struct sessions	sessions;
 | 
			
		||||
struct sessions dead_sessions;
 | 
			
		||||
struct session_groups session_groups;
 | 
			
		||||
 | 
			
		||||
struct winlink *session_next_alert(struct session *, struct winlink *);
 | 
			
		||||
struct winlink *session_previous_alert(struct session *, struct winlink *);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
session_alert_cancel(struct session *s, struct winlink *wl)
 | 
			
		||||
{
 | 
			
		||||
	struct session_alert	*sa, *sb;
 | 
			
		||||
 | 
			
		||||
	sa = SLIST_FIRST(&s->alerts);
 | 
			
		||||
	while (sa != NULL) {
 | 
			
		||||
		sb = sa;
 | 
			
		||||
		sa = SLIST_NEXT(sa, entry);
 | 
			
		||||
 | 
			
		||||
		if (wl == NULL || sb->wl == wl) {
 | 
			
		||||
			SLIST_REMOVE(&s->alerts, sb, session_alert, entry);
 | 
			
		||||
			xfree(sb);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
session_alert_add(struct session *s, struct window *w, int type)
 | 
			
		||||
{
 | 
			
		||||
	struct session_alert	*sa;
 | 
			
		||||
	struct winlink		*wl;
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH(wl, winlinks, &s->windows) {
 | 
			
		||||
		if (wl == s->curw)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (wl->window == w &&
 | 
			
		||||
		    !session_alert_has(s, wl, type)) {
 | 
			
		||||
			sa = xmalloc(sizeof *sa);
 | 
			
		||||
			sa->wl = wl;
 | 
			
		||||
			sa->type = type;
 | 
			
		||||
			SLIST_INSERT_HEAD(&s->alerts, sa, entry);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
session_alert_has(struct session *s, struct winlink *wl, int type)
 | 
			
		||||
{
 | 
			
		||||
	struct session_alert	*sa;
 | 
			
		||||
 | 
			
		||||
	SLIST_FOREACH(sa, &s->alerts, entry) {
 | 
			
		||||
		if (sa->wl == wl && sa->type == type)
 | 
			
		||||
			return (1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
session_alert_has_window(struct session *s, struct window *w, int type)
 | 
			
		||||
{
 | 
			
		||||
	struct session_alert	*sa;
 | 
			
		||||
 | 
			
		||||
	SLIST_FOREACH(sa, &s->alerts, entry) {
 | 
			
		||||
		if (sa->wl->window == w && sa->type == type)
 | 
			
		||||
			return (1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
struct winlink *session_next_alert(struct winlink *);
 | 
			
		||||
struct winlink *session_previous_alert(struct winlink *);
 | 
			
		||||
 | 
			
		||||
/* Find session by name. */
 | 
			
		||||
struct session *
 | 
			
		||||
@@ -134,7 +71,6 @@ session_create(const char *name, const char *cmd, const char *cwd,
 | 
			
		||||
	s->curw = NULL;
 | 
			
		||||
	TAILQ_INIT(&s->lastw);
 | 
			
		||||
	RB_INIT(&s->windows);
 | 
			
		||||
	SLIST_INIT(&s->alerts);
 | 
			
		||||
 | 
			
		||||
	paste_init_stack(&s->buffers);
 | 
			
		||||
 | 
			
		||||
@@ -197,7 +133,6 @@ session_destroy(struct session *s)
 | 
			
		||||
		xfree(s->tio);
 | 
			
		||||
 | 
			
		||||
	session_group_remove(s);
 | 
			
		||||
	session_alert_cancel(s, NULL);
 | 
			
		||||
	environ_free(&s->environ);
 | 
			
		||||
	options_free(&s->options);
 | 
			
		||||
	paste_free_stack(&s->buffers);
 | 
			
		||||
@@ -285,7 +220,7 @@ session_detach(struct session *s, struct winlink *wl)
 | 
			
		||||
	    session_last(s) != 0 && session_previous(s, 0) != 0)
 | 
			
		||||
		session_next(s, 0);
 | 
			
		||||
 | 
			
		||||
	session_alert_cancel(s, wl);
 | 
			
		||||
	wl->flags &= ~WINLINK_ALERTFLAGS;
 | 
			
		||||
	winlink_stack_remove(&s->lastw, wl);
 | 
			
		||||
	winlink_remove(&s->windows, wl);
 | 
			
		||||
	session_group_synchronize_from(s);
 | 
			
		||||
@@ -297,27 +232,23 @@ session_detach(struct session *s, struct winlink *wl)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Return if session has window. */
 | 
			
		||||
int
 | 
			
		||||
struct winlink *
 | 
			
		||||
session_has(struct session *s, struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH(wl, winlinks, &s->windows) {
 | 
			
		||||
		if (wl->window == w)
 | 
			
		||||
			return (1);
 | 
			
		||||
			return (wl);
 | 
			
		||||
	}
 | 
			
		||||
	return (0);
 | 
			
		||||
	return (NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct winlink *
 | 
			
		||||
session_next_alert(struct session *s, struct winlink *wl)
 | 
			
		||||
session_next_alert(struct winlink *wl)
 | 
			
		||||
{
 | 
			
		||||
	while (wl != NULL) {
 | 
			
		||||
		if (session_alert_has(s, wl, WINDOW_BELL))
 | 
			
		||||
			break;
 | 
			
		||||
		if (session_alert_has(s, wl, WINDOW_ACTIVITY))
 | 
			
		||||
			break;
 | 
			
		||||
		if (session_alert_has(s, wl, WINDOW_CONTENT))
 | 
			
		||||
		if (wl->flags & WINLINK_ALERTFLAGS)
 | 
			
		||||
			break;
 | 
			
		||||
		wl = winlink_next(wl);
 | 
			
		||||
	}
 | 
			
		||||
@@ -335,10 +266,10 @@ session_next(struct session *s, int alert)
 | 
			
		||||
 | 
			
		||||
	wl = winlink_next(s->curw);
 | 
			
		||||
	if (alert)
 | 
			
		||||
		wl = session_next_alert(s, wl);
 | 
			
		||||
		wl = session_next_alert(wl);
 | 
			
		||||
	if (wl == NULL) {
 | 
			
		||||
		wl = RB_MIN(winlinks, &s->windows);
 | 
			
		||||
		if (alert && ((wl = session_next_alert(s, wl)) == NULL))
 | 
			
		||||
		if (alert && ((wl = session_next_alert(wl)) == NULL))
 | 
			
		||||
			return (-1);
 | 
			
		||||
	}
 | 
			
		||||
	if (wl == s->curw)
 | 
			
		||||
@@ -346,19 +277,15 @@ session_next(struct session *s, int alert)
 | 
			
		||||
	winlink_stack_remove(&s->lastw, wl);
 | 
			
		||||
	winlink_stack_push(&s->lastw, s->curw);
 | 
			
		||||
	s->curw = wl;
 | 
			
		||||
	session_alert_cancel(s, wl);
 | 
			
		||||
	wl->flags &= ~WINLINK_ALERTFLAGS;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct winlink *
 | 
			
		||||
session_previous_alert(struct session *s, struct winlink *wl)
 | 
			
		||||
session_previous_alert(struct winlink *wl)
 | 
			
		||||
{
 | 
			
		||||
	while (wl != NULL) {
 | 
			
		||||
		if (session_alert_has(s, wl, WINDOW_BELL))
 | 
			
		||||
			break;
 | 
			
		||||
		if (session_alert_has(s, wl, WINDOW_ACTIVITY))
 | 
			
		||||
			break;
 | 
			
		||||
		if (session_alert_has(s, wl, WINDOW_CONTENT))
 | 
			
		||||
		if (wl->flags & WINLINK_ALERTFLAGS)
 | 
			
		||||
			break;
 | 
			
		||||
		wl = winlink_previous(wl);
 | 
			
		||||
	}
 | 
			
		||||
@@ -376,10 +303,10 @@ session_previous(struct session *s, int alert)
 | 
			
		||||
 | 
			
		||||
	wl = winlink_previous(s->curw);
 | 
			
		||||
	if (alert)
 | 
			
		||||
		wl = session_previous_alert(s, wl);
 | 
			
		||||
		wl = session_previous_alert(wl);
 | 
			
		||||
	if (wl == NULL) {
 | 
			
		||||
		wl = RB_MAX(winlinks, &s->windows);
 | 
			
		||||
		if (alert && (wl = session_previous_alert(s, wl)) == NULL)
 | 
			
		||||
		if (alert && (wl = session_previous_alert(wl)) == NULL)
 | 
			
		||||
			return (-1);
 | 
			
		||||
	}
 | 
			
		||||
	if (wl == s->curw)
 | 
			
		||||
@@ -387,7 +314,7 @@ session_previous(struct session *s, int alert)
 | 
			
		||||
	winlink_stack_remove(&s->lastw, wl);
 | 
			
		||||
	winlink_stack_push(&s->lastw, s->curw);
 | 
			
		||||
	s->curw = wl;
 | 
			
		||||
	session_alert_cancel(s, wl);
 | 
			
		||||
	wl->flags &= ~WINLINK_ALERTFLAGS;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -405,7 +332,7 @@ session_select(struct session *s, int idx)
 | 
			
		||||
	winlink_stack_remove(&s->lastw, wl);
 | 
			
		||||
	winlink_stack_push(&s->lastw, s->curw);
 | 
			
		||||
	s->curw = wl;
 | 
			
		||||
	session_alert_cancel(s, wl);
 | 
			
		||||
	wl->flags &= ~WINLINK_ALERTFLAGS;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -424,7 +351,7 @@ session_last(struct session *s)
 | 
			
		||||
	winlink_stack_remove(&s->lastw, wl);
 | 
			
		||||
	winlink_stack_push(&s->lastw, s->curw);
 | 
			
		||||
	s->curw = wl;
 | 
			
		||||
	session_alert_cancel(s, wl);
 | 
			
		||||
	wl->flags &= ~WINLINK_ALERTFLAGS;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -541,7 +468,6 @@ session_group_synchronize1(struct session *target, struct session *s)
 | 
			
		||||
	struct winlinks		 old_windows, *ww;
 | 
			
		||||
	struct winlink_stack	 old_lastw;
 | 
			
		||||
	struct winlink		*wl, *wl2;
 | 
			
		||||
	struct session_alert	*sa;
 | 
			
		||||
 | 
			
		||||
	/* Don't do anything if the session is empty (it'll be destroyed). */
 | 
			
		||||
	ww = &target->windows;
 | 
			
		||||
@@ -559,8 +485,10 @@ session_group_synchronize1(struct session *target, struct session *s)
 | 
			
		||||
	RB_INIT(&s->windows);
 | 
			
		||||
 | 
			
		||||
	/* Link all the windows from the target. */
 | 
			
		||||
	RB_FOREACH(wl, winlinks, ww)
 | 
			
		||||
		winlink_add(&s->windows, wl->window, wl->idx);
 | 
			
		||||
	RB_FOREACH(wl, winlinks, ww) {
 | 
			
		||||
		wl2 = winlink_add(&s->windows, wl->window, wl->idx);
 | 
			
		||||
		wl2->flags |= wl->flags & WINLINK_ALERTFLAGS;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Fix up the current window. */
 | 
			
		||||
	if (s->curw != NULL)
 | 
			
		||||
@@ -577,15 +505,6 @@ session_group_synchronize1(struct session *target, struct session *s)
 | 
			
		||||
			TAILQ_INSERT_TAIL(&s->lastw, wl2, sentry);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* And update the alerts list. */
 | 
			
		||||
	SLIST_FOREACH(sa, &s->alerts, entry) {
 | 
			
		||||
		wl = winlink_find_by_index(&s->windows, sa->wl->idx);
 | 
			
		||||
		if (wl == NULL)
 | 
			
		||||
			session_alert_cancel(s, sa->wl);
 | 
			
		||||
		else
 | 
			
		||||
			sa->wl = wl;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Then free the old winlinks list. */
 | 
			
		||||
	while (!RB_EMPTY(&old_windows)) {
 | 
			
		||||
		wl = RB_ROOT(&old_windows);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user