diff --git a/cmd-choose-window.c b/cmd-choose-window.c index f8318105..e341dd41 100644 --- a/cmd-choose-window.c +++ b/cmd-choose-window.c @@ -81,11 +81,11 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx) idx++; flag = ' '; - if (session_alert_has(s, wm, WINDOW_ACTIVITY)) + if (wm->flags & WINLINK_ACTIVITY) flag = '#'; - else if (session_alert_has(s, wm, WINDOW_BELL)) + else if (wm->flags & WINLINK_BELL) flag = '!'; - else if (session_alert_has(s, wm, WINDOW_CONTENT)) + else if (wm->flags & WINLINK_CONTENT) flag = '+'; else if (wm == s->curw) flag = '*'; diff --git a/cmd-new-window.c b/cmd-new-window.c index cf32f29e..32c42eb4 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -162,7 +162,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx) * Can't use session_detach as it will destroy session if this * makes it empty. */ - session_alert_cancel(s, wl); + wl->flags &= ~WINLINK_ALERTFLAGS; winlink_stack_remove(&s->lastw, wl); winlink_remove(&s->windows, wl); diff --git a/resize.c b/resize.c index 5635f9d4..15f99e7c 100644 --- a/resize.c +++ b/resize.c @@ -105,7 +105,7 @@ recalculate_sizes(void) if (flag) has = s->curw->window == w; else - has = session_has(s, w); + has = session_has(s, w) != NULL; if (has) { if (s->sx < ssx) ssx = s->sx; diff --git a/server-fn.c b/server-fn.c index 01e78ba2..da156e46 100644 --- a/server-fn.c +++ b/server-fn.c @@ -184,7 +184,7 @@ server_status_window(struct window *w) for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { s = ARRAY_ITEM(&sessions, i); - if (s != NULL && session_has(s, w)) + if (s != NULL && session_has(s, w) != NULL) server_status_session(s); } } @@ -249,7 +249,7 @@ server_kill_window(struct window *w) for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { s = ARRAY_ITEM(&sessions, i); - if (s == NULL || !session_has(s, w)) + if (s == NULL || session_has(s, w) == NULL) continue; while ((wl = winlink_find_by_window(&s->windows, w)) != NULL) { if (session_detach(s, wl)) { @@ -286,7 +286,7 @@ server_link_window(struct session *src, struct winlink *srcwl, * Can't use session_detach as it will destroy session * if this makes it empty. */ - session_alert_cancel(dst, dstwl); + dstwl->flags &= ~WINLINK_ALERTFLAGS; winlink_stack_remove(&dst->lastw, dstwl); winlink_remove(&dst->windows, dstwl); diff --git a/server-window.c b/server-window.c index acac83c0..42a4a699 100644 --- a/server-window.c +++ b/server-window.c @@ -24,10 +24,10 @@ #include "tmux.h" int server_window_backoff(struct window_pane *); -int server_window_check_bell(struct session *, struct window *); -int server_window_check_activity(struct session *, struct window *); +int server_window_check_bell(struct session *, struct winlink *); +int server_window_check_activity(struct session *, struct winlink *); int server_window_check_content( - struct session *, struct window *, struct window_pane *); + struct session *, struct winlink *, struct window_pane *); /* Check if this window should suspend reading. */ int @@ -59,6 +59,7 @@ void server_window_loop(void) { struct window *w; + struct winlink *wl; struct window_pane *wp; struct session *s; u_int i, j; @@ -81,33 +82,37 @@ server_window_loop(void) for (j = 0; j < ARRAY_LENGTH(&sessions); j++) { s = ARRAY_ITEM(&sessions, j); - if (s == NULL || !session_has(s, w)) + if (s == NULL) + continue; + wl = session_has(s, w); + if (wl == NULL) continue; - if (server_window_check_bell(s, w) || - server_window_check_activity(s, w)) + if (server_window_check_bell(s, wl) || + server_window_check_activity(s, wl)) server_status_session(s); TAILQ_FOREACH(wp, &w->panes, entry) - server_window_check_content(s, w, wp); + server_window_check_content(s, wl, wp); } - w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_CONTENT); + w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY); } } /* Check for bell in window. */ int -server_window_check_bell(struct session *s, struct window *w) +server_window_check_bell(struct session *s, struct winlink *wl) { struct client *c; + struct window *w = wl->window; u_int i; int action, visual; - if (!(w->flags & WINDOW_BELL)) + if (!(w->flags & WINDOW_BELL) || wl->flags & WINLINK_BELL) + return (0); + if (s->curw == wl) return (0); - if (session_alert_has_window(s, w, WINDOW_BELL)) - return (0); - session_alert_add(s, w, WINDOW_BELL); + wl->flags |= WINLINK_BELL; action = options_get_number(&s->options, "bell-action"); switch (action) { @@ -155,25 +160,22 @@ server_window_check_bell(struct session *s, struct window *w) /* Check for activity in window. */ int -server_window_check_activity(struct session *s, struct window *w) +server_window_check_activity(struct session *s, struct winlink *wl) { struct client *c; + struct window *w = wl->window; u_int i; - if (!(w->flags & WINDOW_ACTIVITY)) + if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_ACTIVITY) return (0); - if (s->curw->window == w) + if (s->curw == wl) return (0); if (!options_get_number(&w->options, "monitor-activity")) return (0); - if (session_alert_has_window(s, w, WINDOW_ACTIVITY)) - return (0); - session_alert_add(s, w, WINDOW_ACTIVITY); + wl->flags |= WINLINK_ACTIVITY; - if (s->flags & SESSION_UNATTACHED) - return (0); if (options_get_number(&s->options, "visual-activity")) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); @@ -190,31 +192,28 @@ server_window_check_activity(struct session *s, struct window *w) /* Check for content change in window. */ int server_window_check_content( - struct session *s, struct window *w, struct window_pane *wp) + struct session *s, struct winlink *wl, struct window_pane *wp) { struct client *c; + struct window *w = wl->window; u_int i; char *found, *ptr; - if (!(w->flags & WINDOW_ACTIVITY)) /* activity for new content */ + /* Activity flag must be set for new content. */ + if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_CONTENT) return (0); - if (s->curw->window == w) + if (s->curw == wl) return (0); ptr = options_get_string(&w->options, "monitor-content"); if (ptr == NULL || *ptr == '\0') return (0); - - if (session_alert_has_window(s, w, WINDOW_CONTENT)) - return (0); - if ((found = window_pane_search(wp, ptr, NULL)) == NULL) return (0); xfree(found); - session_alert_add(s, w, WINDOW_CONTENT); - if (s->flags & SESSION_UNATTACHED) - return (0); + wl->flags |= WINLINK_CONTENT; + if (options_get_number(&s->options, "visual-content")) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); diff --git a/session.c b/session.c index 2957c1fc..65f8ef41 100644 --- a/session.c +++ b/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); diff --git a/status.c b/status.c index 4399ae43..b1d93c97 100644 --- a/status.c +++ b/status.c @@ -248,25 +248,15 @@ status_redraw(struct client *c) */ offset = 0; RB_FOREACH(wl, winlinks, &s->windows) { - if (larrow == 1 && offset < wlstart) { - if (session_alert_has(s, wl, WINDOW_ACTIVITY)) - larrow = -1; - else if (session_alert_has(s, wl, WINDOW_BELL)) - larrow = -1; - else if (session_alert_has(s, wl, WINDOW_CONTENT)) - larrow = -1; - } + if (wl->flags & WINLINK_ALERTFLAGS && + larrow == 1 && offset < wlstart) + larrow = -1; offset += wl->status_width; - if (rarrow == 1 && offset > wlstart + wlwidth) { - if (session_alert_has(s, wl, WINDOW_ACTIVITY)) - rarrow = -1; - else if (session_alert_has(s, wl, WINDOW_BELL)) - rarrow = -1; - else if (session_alert_has(s, wl, WINDOW_CONTENT)) - rarrow = -1; - } + if (wl->flags & WINLINK_ALERTFLAGS && + rarrow == 1 && offset > wlstart + wlwidth) + rarrow = -1; } draw: @@ -399,11 +389,11 @@ status_replace1(struct client *c,struct winlink *wl, goto do_replace; case 'F': tmp[0] = ' '; - if (session_alert_has(s, wl, WINDOW_CONTENT)) + if (wl->flags & WINLINK_CONTENT) tmp[0] = '+'; - else if (session_alert_has(s, wl, WINDOW_BELL)) + else if (wl->flags & WINLINK_BELL) tmp[0] = '!'; - else if (session_alert_has(s, wl, WINDOW_ACTIVITY)) + else if (wl->flags & WINLINK_ACTIVITY) tmp[0] = '#'; else if (wl == s->curw) tmp[0] = '*'; @@ -593,9 +583,7 @@ status_print( fmt = options_get_string(oo, "window-status-current-format"); } - if (session_alert_has(s, wl, WINDOW_ACTIVITY) || - session_alert_has(s, wl, WINDOW_BELL) || - session_alert_has(s, wl, WINDOW_CONTENT)) { + if (wl->flags & WINLINK_ALERTFLAGS) { fg = options_get_number(oo, "window-status-alert-fg"); if (fg != 8) colour_set_fg(gc, fg); diff --git a/tmux.h b/tmux.h index c090aedd..10f3e593 100644 --- a/tmux.h +++ b/tmux.h @@ -843,8 +843,7 @@ struct window { #define WINDOW_BELL 0x1 #define WINDOW_HIDDEN 0x2 #define WINDOW_ACTIVITY 0x4 -#define WINDOW_CONTENT 0x8 -#define WINDOW_REDRAW 0x10 +#define WINDOW_REDRAW 0x8 struct options options; @@ -861,6 +860,12 @@ struct winlink { struct grid_cell status_cell; char *status_text; + int flags; +#define WINLINK_BELL 0x1 +#define WINLINK_ACTIVITY 0x2 +#define WINLINK_CONTENT 0x4 +#define WINLINK_ALERTFLAGS (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_CONTENT) + RB_ENTRY(winlink) entry; TAILQ_ENTRY(winlink) sentry; }; @@ -912,13 +917,6 @@ struct environ_entry { RB_HEAD(environ, environ_entry); /* Client session. */ -struct session_alert { - struct winlink *wl; - int type; - - SLIST_ENTRY(session_alert) entry; -}; - struct session_group { TAILQ_HEAD(, session) sessions; @@ -943,8 +941,6 @@ struct session { struct paste_stack buffers; - SLIST_HEAD(, session_alert) alerts; - #define SESSION_UNATTACHED 0x1 /* not attached to any clients */ #define SESSION_DEAD 0x2 int flags; @@ -1911,10 +1907,6 @@ void clear_signals(void); extern struct sessions sessions; extern struct sessions dead_sessions; extern struct session_groups session_groups; -void session_alert_add(struct session *, struct window *, int); -void session_alert_cancel(struct session *, struct winlink *); -int session_alert_has(struct session *, struct winlink *, int); -int session_alert_has_window(struct session *, struct window *, int); struct session *session_find(const char *); struct session *session_create(const char *, const char *, const char *, struct environ *, struct termios *, int, u_int, u_int, @@ -1926,7 +1918,7 @@ struct winlink *session_new(struct session *, struct winlink *session_attach( struct session *, struct window *, int, char **); int session_detach(struct session *, struct winlink *); -int session_has(struct session *, struct window *); +struct winlink* session_has(struct session *, struct window *); int session_next(struct session *, int); int session_previous(struct session *, int); int session_select(struct session *, int);