From 75d10058a41d8e95dda126d460a119a9037e9345 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 28 Aug 2015 12:16:28 +0000 Subject: [PATCH] Run status update on a per-client timer at status-interval. --- cmd-attach-session.c | 2 ++ cmd-new-session.c | 1 + cmd-set-option.c | 5 +++- cmd-switch-client.c | 1 + format.c | 2 +- server-client.c | 38 ++---------------------------- server-fn.c | 1 + server.c | 2 -- status.c | 56 ++++++++++++++++++++++++++++++++++++++++---- tmux.h | 4 +++- 10 files changed, 67 insertions(+), 45 deletions(-) diff --git a/cmd-attach-session.c b/cmd-attach-session.c index e7cde0f0..9f357d6e 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -133,6 +133,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag, } c->session = s; + status_timer_start(c); notify_attached_session_changed(c); session_update_activity(s); server_redraw_client(c); @@ -177,6 +178,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag, } c->session = s; + status_timer_start(c); notify_attached_session_changed(c); session_update_activity(s); server_redraw_client(c); diff --git a/cmd-new-session.c b/cmd-new-session.c index 1533e5f0..2125ee88 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -275,6 +275,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) else if (c->session != NULL) c->last_session = c->session; c->session = s; + status_timer_start(c); notify_attached_session_changed(c); session_update_activity(s); server_redraw_client(c); diff --git a/cmd-set-option.c b/cmd-set-option.c index 761cee93..260961cb 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -176,7 +176,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); } - /* Start or stop timers when automatic-rename changed. */ + /* Start or stop timers when name or status options changed. */ if (strcmp(oe->name, "automatic-rename") == 0) { RB_FOREACH(w, windows, &windows) { if (options_get_number(&w->options, "automatic-rename")) @@ -185,6 +185,9 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) evtimer_del(&w->name_timer); } } + if (strcmp(oe->name, "status") == 0 || + strcmp(oe->name, "status-interval") == 0) + status_timer_start_all(); /* Update sizes and redraw. May not need it but meh. */ recalculate_sizes(); diff --git a/cmd-switch-client.c b/cmd-switch-client.c index 4bac540d..6a79c7b7 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -127,6 +127,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq) if (c->session != NULL) c->last_session = c->session; c->session = s; + status_timer_start(c); session_update_activity(s); recalculate_sizes(); diff --git a/format.c b/format.c index 09b16e76..39843674 100644 --- a/format.c +++ b/format.c @@ -247,7 +247,7 @@ format_job_timer(unused int fd, unused short events, unused void *arg) if (fj->job != NULL) job_free(fj->job); - free((void*)fj->cmd); + free((void *)fj->cmd); free(fj->out); free(fj); diff --git a/server-client.c b/server-client.c index f33018e4..82cec36c 100644 --- a/server-client.c +++ b/server-client.c @@ -188,6 +188,8 @@ server_client_lost(struct client *c) if (c->stderr_data != c->stdout_data) evbuffer_free(c->stderr_data); + if (event_initialized(&c->status_timer)) + evtimer_del(&c->status_timer); screen_free(&c->status); free(c->title); @@ -289,42 +291,6 @@ client_lost: server_client_lost(c); } -/* Handle client status timer. */ -void -server_client_status_timer(void) -{ - struct client *c; - struct session *s; - struct timeval tv; - int interval; - time_t difference; - - if (gettimeofday(&tv, NULL) != 0) - fatal("gettimeofday failed"); - - TAILQ_FOREACH(c, &clients, entry) { - if (c->session == NULL) - continue; - if (c->message_string != NULL || c->prompt_string != NULL) { - /* - * Don't need timed redraw for messages/prompts so bail - * now. The status timer isn't reset when they are - * redrawn anyway. - */ - continue; - } - s = c->session; - - if (!options_get_number(&s->options, "status")) - continue; - interval = options_get_number(&s->options, "status-interval"); - - difference = tv.tv_sec - c->status_timer.tv_sec; - if (interval != 0 && difference >= interval) - c->flags |= CLIENT_STATUS; - } -} - /* Check for mouse keys. */ int server_client_check_mouse(struct client *c) diff --git a/server-fn.c b/server-fn.c index 0e6e4d46..469dd82d 100644 --- a/server-fn.c +++ b/server-fn.c @@ -419,6 +419,7 @@ server_destroy_session(struct session *s) } else { c->last_session = NULL; c->session = s_new; + status_timer_start(c); notify_attached_session_changed(c); session_update_activity(s_new); server_redraw_client(c); diff --git a/server.c b/server.c index c4de510e..cfd2dd34 100644 --- a/server.c +++ b/server.c @@ -520,8 +520,6 @@ server_second_callback(unused int fd, unused short events, unused void *arg) } } - server_client_status_timer(); - evtimer_del(&server_ev_second); memset(&tv, 0, sizeof tv); tv.tv_sec = 1; diff --git a/status.c b/status.c index d9501f02..93cee2b1 100644 --- a/status.c +++ b/status.c @@ -37,6 +37,7 @@ char *status_print(struct client *, struct winlink *, time_t, struct grid_cell *); char *status_replace(struct client *, struct winlink *, const char *, time_t); void status_message_callback(int, short, void *); +void status_timer_callback(int, short, void *); const char *status_prompt_up_history(u_int *); const char *status_prompt_down_history(u_int *); @@ -142,6 +143,55 @@ status_prompt_save_history(void) } +/* Status timer callback. */ +void +status_timer_callback(unused int fd, unused short events, void *arg) +{ + struct client *c = arg; + struct session *s = c->session; + struct timeval tv; + + evtimer_del(&c->status_timer); + + if (s == NULL) + return; + + if (c->message_string == NULL && c->prompt_string == NULL) + c->flags |= CLIENT_STATUS; + + timerclear(&tv); + tv.tv_sec = options_get_number(&s->options, "status-interval"); + + if (tv.tv_sec != 0) + evtimer_add(&c->status_timer, &tv); + log_debug("client %d, status interval %d", c->ibuf.fd, (int)tv.tv_sec); +} + +/* Start status timer for client. */ +void +status_timer_start(struct client *c) +{ + struct session *s = c->session; + + if (event_initialized(&c->status_timer)) + evtimer_del(&c->status_timer); + else + evtimer_set(&c->status_timer, status_timer_callback, c); + + if (s != NULL && options_get_number(&s->options, "status")) + status_timer_callback(-1, 0, c); +} + +/* Start status timer for all clients. */ +void +status_timer_start_all(void) +{ + struct client *c; + + TAILQ_FOREACH(c, &clients, entry) + status_timer_start(c); +} + /* Get screen line of status line. -1 means off. */ int status_at_line(struct client *c) @@ -244,10 +294,8 @@ status_redraw(struct client *c) left = right = NULL; larrow = rarrow = 0; - /* Update status timer. */ - if (gettimeofday(&c->status_timer, NULL) != 0) - fatal("gettimeofday failed"); - t = c->status_timer.tv_sec; + /* Store current time. */ + t = time(NULL); /* Set up default colour. */ style_apply(&stdgc, &s->options, "status-style"); diff --git a/tmux.h b/tmux.h index 5859cc53..6b82e79c 100644 --- a/tmux.h +++ b/tmux.h @@ -1207,7 +1207,7 @@ struct client { struct event repeat_timer; - struct timeval status_timer; + struct event status_timer; struct screen status; #define CLIENT_TERMINAL 0x1 @@ -1893,6 +1893,8 @@ int server_set_stdin_callback(struct client *, void (*)(struct client *, void server_unzoom_window(struct window *); /* status.c */ +void status_timer_start(struct client *); +void status_timer_start_all(void); int status_at_line(struct client *); struct window *status_get_window_at(struct client *, u_int); int status_redraw(struct client *);