From 14b951254674c75d8422a8ac5f320a54d1dd8a48 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 4 Jun 2008 16:46:23 +0000 Subject: [PATCH] Add activity monitoring, also invert items on taskbar which have activity. --- CHANGES | 5 ++++- cmd-link-window.c | 4 ++-- input.c | 4 +++- server.c | 31 +++++++++++++++++---------- session.c | 54 +++++++++++++++++++++++++++++------------------ status.c | 19 +++++++++++++---- tmux.h | 29 +++++++++++++++---------- 7 files changed, 95 insertions(+), 51 deletions(-) diff --git a/CHANGES b/CHANGES index 16f54a30..28922944 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ 04 June 2008 +* Change so active/bell windows are inverted in status line. +* Activity monitoring - window with activity are marked in status line. No + way to disable this/filter windows yet. * Brought select-window command into line with everything else; it now uses -i for the window index. * Strings to display on the left and right of the status bar may now be set @@ -393,4 +396,4 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.105 2008-06-04 16:11:52 nicm Exp $ +$Id: CHANGES,v 1.106 2008-06-04 16:46:23 nicm Exp $ diff --git a/cmd-link-window.c b/cmd-link-window.c index f31c824d..e43c9ad9 100644 --- a/cmd-link-window.c +++ b/cmd-link-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-link-window.c,v 1.15 2008-06-03 16:55:09 nicm Exp $ */ +/* $Id: cmd-link-window.c,v 1.16 2008-06-04 16:46:23 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -168,7 +168,7 @@ cmd_link_window_exec(void *ptr, struct cmd_ctx *ctx) * Can't use session_detach as it will destroy session if this * makes it empty. */ - session_cancelbell(s, wl2); + session_alert_cancel(s, wl2); winlink_remove(&s->windows, wl2); /* Force select/redraw if current. */ diff --git a/input.c b/input.c index 13532cca..969991e1 100644 --- a/input.c +++ b/input.c @@ -1,4 +1,4 @@ -/* $Id: input.c,v 1.46 2008-01-03 21:32:11 nicm Exp $ */ +/* $Id: input.c,v 1.47 2008-06-04 16:46:23 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -223,6 +223,8 @@ input_parse(struct window *w) else screen_write_start(&ictx->ctx, &w->base, NULL, NULL); + if (ictx->off != ictx->len) + w->flags |= WINDOW_ACTIVITY; while (ictx->off < ictx->len) { ch = ictx->buf[ictx->off++]; ictx->state(ch, ictx); diff --git a/server.c b/server.c index ff2411c7..ab1d90c2 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.51 2008-06-04 05:47:46 nicm Exp $ */ +/* $Id: server.c,v 1.52 2008-06-04 16:46:23 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -415,31 +415,40 @@ server_handle_window(struct window *w) { struct session *s; u_int i; + int action; window_parse(w); - if (!(w->flags & WINDOW_BELL)) + if (!(w->flags & (WINDOW_BELL|WINDOW_ACTIVITY))) return; for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { s = ARRAY_ITEM(&sessions, i); if (s == NULL || !session_has(s, w)) continue; - session_addbell(s, w); - switch (options_get_number(&s->options, "bell-action")) { - case BELL_ANY: - tty_write_session(s, TTY_CHARACTER, '\007'); - break; - case BELL_CURRENT: - if (s->curw->window == w) + if (w->flags & WINDOW_BELL) { + session_alert_add(s, w, WINDOW_BELL); + + action = options_get_number(&s->options, "bell-action"); + switch (action) { + case BELL_ANY: tty_write_session(s, TTY_CHARACTER, '\007'); - break; + break; + case BELL_CURRENT: + if (s->curw->window != w) + break; + tty_write_session(s, TTY_CHARACTER, '\007'); + break; + } } + + if (w->flags & WINDOW_ACTIVITY) + session_alert_add(s, w, WINDOW_ACTIVITY); } server_status_window(w); - w->flags &= ~WINDOW_BELL; + w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY); } /* Lost window: move clients on to next window. */ diff --git a/session.c b/session.c index 0748c117..52d7fd0f 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $Id: session.c,v 1.33 2008-06-03 21:42:37 nicm Exp $ */ +/* $Id: session.c,v 1.34 2008-06-04 16:46:23 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -29,40 +29,51 @@ struct sessions sessions; void -session_cancelbell(struct session *s, struct winlink *wl) +session_alert_cancel(struct session *s, struct winlink *wl) { - u_int i; + struct session_alert *sa, *sb; - for (i = 0; i < ARRAY_LENGTH(&s->bells); i++) { - if (ARRAY_ITEM(&s->bells, i) == wl) { - ARRAY_REMOVE(&s->bells, i); - break; + sa = TAILQ_FIRST(&s->alerts); + while (sa != NULL) { + sb = sa; + sa = TAILQ_NEXT(sa, entry); + + if (wl == NULL || sb->wl == wl) { + TAILQ_REMOVE(&s->alerts, sb, entry); + xfree(sb); } } } void -session_addbell(struct session *s, struct window *w) +session_alert_add(struct session *s, struct window *w, int type) { - struct winlink *wl; + struct session_alert *sa; + struct winlink *wl; RB_FOREACH(wl, winlinks, &s->windows) { if (wl == s->curw) continue; - if (wl->window == w && !session_hasbell(s, wl)) - ARRAY_ADD(&s->bells, wl); + + if (wl->window == w && !session_alert_has(s, wl, type)) { + sa = xmalloc(sizeof *sa); + sa->wl = wl; + sa->type = type; + TAILQ_INSERT_HEAD(&s->alerts, sa, entry); + } } } int -session_hasbell(struct session *s, struct winlink *wl) +session_alert_has(struct session *s, struct winlink *wl, int type) { - u_int i; + struct session_alert *sa; - for (i = 0; i < ARRAY_LENGTH(&s->bells); i++) { - if (ARRAY_ITEM(&s->bells, i) == wl) + TAILQ_FOREACH(sa, &s->alerts, entry) { + if (sa->wl == wl && sa->type == type) return (1); } + return (0); } @@ -94,7 +105,7 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy) fatal("clock_gettime"); s->curw = s->lastw = NULL; RB_INIT(&s->windows); - ARRAY_INIT(&s->bells); + TAILQ_INIT(&s->alerts); options_init(&s->options, &global_options); s->sx = sx; @@ -138,6 +149,7 @@ session_destroy(struct session *s) while (!ARRAY_EMPTY(&sessions) && ARRAY_LAST(&sessions) == NULL) ARRAY_TRUNC(&sessions, 1); + session_alert_cancel(s, NULL); options_free(&s->options); while (!RB_EMPTY(&s->windows)) @@ -194,7 +206,7 @@ session_detach(struct session *s, struct winlink *wl) if (s->lastw == wl) s->lastw = NULL; - session_cancelbell(s, wl); + session_alert_cancel(s, wl); winlink_remove(&s->windows, wl); if (RB_EMPTY(&s->windows)) { session_destroy(s); @@ -232,7 +244,7 @@ session_next(struct session *s) return (1); s->lastw = s->curw; s->curw = wl; - session_cancelbell(s, wl); + session_alert_cancel(s, wl); return (0); } @@ -252,7 +264,7 @@ session_previous(struct session *s) return (1); s->lastw = s->curw; s->curw = wl; - session_cancelbell(s, wl); + session_alert_cancel(s, wl); return (0); } @@ -269,7 +281,7 @@ session_select(struct session *s, int idx) return (1); s->lastw = s->curw; s->curw = wl; - session_cancelbell(s, wl); + session_alert_cancel(s, wl); return (0); } @@ -287,6 +299,6 @@ session_last(struct session *s) s->lastw = s->curw; s->curw = wl; - session_cancelbell(s, wl); + session_alert_cancel(s, wl); return (0); } diff --git a/status.c b/status.c index 18f5b6a1..4b934382 100644 --- a/status.c +++ b/status.c @@ -1,4 +1,4 @@ -/* $Id: status.c,v 1.20 2008-06-04 05:40:35 nicm Exp $ */ +/* $Id: status.c,v 1.21 2008-06-04 16:46:23 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -65,11 +65,22 @@ status_write_client(struct client *c) flag = '-'; if (wl == c->session->curw) flag = '*'; - if (session_hasbell(c->session, wl)) + if (session_alert_has(c->session, wl, WINDOW_ACTIVITY)) { + flag = '#'; + screen_redraw_set_attributes( + &ctx, ATTR_REVERSE, scolour); + } + if (session_alert_has(c->session, wl, WINDOW_BELL)) { flag = '!'; + screen_redraw_set_attributes( + &ctx, ATTR_REVERSE, scolour); + } screen_redraw_write_string( - &ctx, "%d:%s%c ", wl->idx, wl->window->name, flag); - + &ctx, "%d:%s%c", wl->idx, wl->window->name, flag); + if (flag == '!' || flag == '#') + screen_redraw_set_attributes(&ctx, 0, scolour); + screen_redraw_write_string(&ctx, " "); + if (ctx.s->cx > screen_size_x(ctx.s) - rlen) break; } diff --git a/tmux.h b/tmux.h index 38f25910..8f5582ba 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.127 2008-06-04 16:11:53 nicm Exp $ */ +/* $Id: tmux.h,v 1.128 2008-06-04 16:46:23 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -105,6 +105,11 @@ struct buffer { size_t off; /* offset of data in buffer */ }; +/* Bell option values. */ +#define BELL_NONE 0 +#define BELL_ANY 1 +#define BELL_CURRENT 2 + /* Key codes. ncurses defines KEY_*. Grrr. */ #define KEYC_NONE 256 #define KEYC_A1 -1 @@ -513,6 +518,7 @@ struct window { int flags; #define WINDOW_BELL 0x1 #define WINDOW_HIDDEN 0x2 +#define WINDOW_ACTIVITY 0x4 struct screen *screen; struct screen base; @@ -555,6 +561,13 @@ struct options { }; /* Client session. */ +struct session_alert { + struct winlink *wl; + int type; + + TAILQ_ENTRY(session_alert) entry; +}; + struct session { char *name; struct timespec ts; @@ -568,7 +581,7 @@ struct session { struct options options; - ARRAY_DECL(, struct winlink *) bells; /* windows with bells */ + TAILQ_HEAD(, session_alert) alerts; #define SESSION_UNATTACHED 0x1 /* not attached to any clients */ int flags; @@ -722,16 +735,10 @@ size_t strlcat(char *, const char *, size_t); /* tmux.c */ extern volatile sig_atomic_t sigwinch; extern volatile sig_atomic_t sigterm; -#define BELL_NONE 0 -#define BELL_ANY 1 -#define BELL_CURRENT 2 extern struct options global_options; -extern char *default_command; extern char *cfg_file; extern char *paste_buffer; -extern int bell_action; extern int debug_level; -extern u_int history_limit; void logfile(const char *); void siginit(void); void sigreset(void); @@ -1038,9 +1045,9 @@ void printflike2 window_more_add(struct window *, const char *, ...); /* session.c */ extern struct sessions sessions; -void session_cancelbell(struct session *, struct winlink *); -void session_addbell(struct session *, struct window *); -int session_hasbell(struct session *, struct winlink *); +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); struct session *session_find(const char *); struct session *session_create(const char *, const char *, u_int, u_int); void session_destroy(struct session *);