diff options
-rw-r--r-- | cmd-attach-session.c | 2 | ||||
-rw-r--r-- | cmd-new-session.c | 1 | ||||
-rw-r--r-- | cmd-set-option.c | 5 | ||||
-rw-r--r-- | cmd-switch-client.c | 1 | ||||
-rw-r--r-- | format.c | 19 | ||||
-rw-r--r-- | log.c | 4 | ||||
-rw-r--r-- | options-table.c | 5 | ||||
-rw-r--r-- | server-client.c | 38 | ||||
-rw-r--r-- | server-fn.c | 1 | ||||
-rw-r--r-- | server.c | 40 | ||||
-rw-r--r-- | status.c | 56 | ||||
-rw-r--r-- | tmux.1 | 17 | ||||
-rw-r--r-- | tmux.h | 6 | ||||
-rw-r--r-- | window-choose.c | 1 | ||||
-rw-r--r-- | window-clock.c | 50 | ||||
-rw-r--r-- | window-copy.c | 1 |
16 files changed, 118 insertions, 129 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(); @@ -38,6 +38,7 @@ void format_job_callback(struct job *); const char *format_job_get(struct format_tree *, const char *); +void format_job_timer(int, short, void *); int format_replace(struct format_tree *, const char *, size_t, char **, size_t *, size_t *); @@ -64,6 +65,7 @@ struct format_job { }; /* Format job tree. */ +struct event format_job_event; int format_job_cmp(struct format_job *, struct format_job *); RB_HEAD(format_job_tree, format_job) format_jobs = RB_INITIALIZER(); RB_PROTOTYPE(format_job_tree, format_job, entry, format_job_cmp); @@ -192,6 +194,8 @@ format_job_callback(struct job *job) server_status_client(c); fj->status = 0; } + + log_debug("%s: %s: %s", __func__, fj->cmd, fj->out); } /* Find a job. */ @@ -227,10 +231,11 @@ format_job_get(struct format_tree *ft, const char *cmd) /* Remove old jobs. */ void -format_clean(void) +format_job_timer(unused int fd, unused short events, unused void *arg) { struct format_job *fj, *fj1; time_t now; + struct timeval tv = { .tv_sec = 60 }; now = time(NULL); RB_FOREACH_SAFE(fj, format_job_tree, &format_jobs, fj1) { @@ -238,14 +243,19 @@ format_clean(void) continue; RB_REMOVE(format_job_tree, &format_jobs, fj); + log_debug("%s: %s", __func__, fj->cmd); + if (fj->job != NULL) job_free(fj->job); - free((void*)fj->cmd); + free((void *)fj->cmd); free(fj->out); free(fj); } + + evtimer_del(&format_job_event); + evtimer_add(&format_job_event, &tv); } /* Create a new tree. */ @@ -262,6 +272,11 @@ format_create_status(int status) struct format_tree *ft; char host[HOST_NAME_MAX + 1], *ptr; + if (!event_initialized(&format_job_event)) { + evtimer_set(&format_job_event, format_job_timer, NULL); + format_job_timer(-1, 0, NULL); + } + ft = xcalloc(1, sizeof *ft); RB_INIT(&ft->tree); ft->status = status; @@ -68,11 +68,13 @@ void log_vwrite(const char *msg, va_list ap) { char *fmt; + time_t t; if (log_file == NULL) return; - if (asprintf(&fmt, "%s\n", msg) == -1) + t = time(NULL); + if (asprintf(&fmt, "%lld %s\n", (long long)t, msg) == -1) exit(1); if (vfprintf(log_file, fmt, ap) == -1) exit(1); diff --git a/options-table.c b/options-table.c index 1c9ccd95..c99937d3 100644 --- a/options-table.c +++ b/options-table.c @@ -205,11 +205,6 @@ const struct options_table_entry session_options_table[] = { .default_str = "lock -np" }, - { .name = "lock-server", - .type = OPTIONS_TABLE_FLAG, - .default_num = 1 - }, - { .name = "message-attr", .type = OPTIONS_TABLE_ATTRIBUTES, .default_num = 0, diff --git a/server-client.c b/server-client.c index ad66a3fe..fab1c1a0 100644 --- a/server-client.c +++ b/server-client.c @@ -187,6 +187,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); @@ -288,42 +290,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 668ef5c4..b7ff9443 100644 --- a/server-fn.c +++ b/server-fn.c @@ -422,6 +422,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); @@ -63,7 +63,6 @@ void server_child_signal(void); void server_child_exited(pid_t, int); void server_child_stopped(pid_t, int); void server_second_callback(int, short, void *); -void server_lock_server(void); void server_lock_sessions(void); /* Set marked pane. */ @@ -505,25 +504,9 @@ server_child_stopped(pid_t pid, int status) void server_second_callback(unused int fd, unused short events, unused void *arg) { - struct window *w; - struct window_pane *wp; struct timeval tv; - if (options_get_number(&global_s_options, "lock-server")) - server_lock_server(); - else - server_lock_sessions(); - - RB_FOREACH(w, windows, &windows) { - TAILQ_FOREACH(wp, &w->panes, entry) { - if (wp->mode != NULL && wp->mode->timer != NULL) - wp->mode->timer(wp); - } - } - - server_client_status_timer(); - - format_clean(); + server_lock_sessions(); evtimer_del(&server_ev_second); memset(&tv, 0, sizeof tv); @@ -531,27 +514,6 @@ server_second_callback(unused int fd, unused short events, unused void *arg) evtimer_add(&server_ev_second, &tv); } -/* Lock the server if ALL sessions have hit the time limit. */ -void -server_lock_server(void) -{ - struct session *s; - int timeout; - time_t t; - - t = time(NULL); - RB_FOREACH(s, sessions, &sessions) { - if (s->flags & SESSION_UNATTACHED) - continue; - timeout = options_get_number(&s->options, "lock-after-time"); - if (timeout <= 0 || t <= s->activity_time.tv_sec + timeout) - return; /* not timed out */ - } - - server_lock(); - recalculate_sizes(); -} - /* Lock any sessions which have timed out. */ void server_lock_sessions(void) @@ -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"); @@ -2565,9 +2565,7 @@ Lock the session (like the .Ic lock-session command) after .Ar number -seconds of inactivity, or the entire server (all sessions) if the -.Ic lock-server -option is set. +seconds of inactivity. The default is not to lock (set to 0). .It Ic lock-command Ar shell-command Command to run when locking each client. @@ -2575,19 +2573,6 @@ The default is to run .Xr lock 1 with .Fl np . -.It Xo Ic lock-server -.Op Ic on | off -.Xc -If this option is -.Ic on -(the default), -instead of each session locking individually as each has been -idle for -.Ic lock-after-time , -the entire server will lock after -.Em all -sessions would have locked. -This has no effect as a session option; it must be set as a global option. .It Ic message-command-style Ar style Set status line message command style, where .Ar style @@ -781,7 +781,6 @@ struct window_mode { void (*resize)(struct window_pane *, u_int, u_int); void (*key)(struct window_pane *, struct client *, struct session *, int, struct mouse_event *); - void (*timer)(struct window_pane *); }; /* Structures for choose mode. */ @@ -1211,7 +1210,7 @@ struct client { struct event repeat_timer; - struct timeval status_timer; + struct event status_timer; struct screen status; #define CLIENT_TERMINAL 0x1 @@ -1453,7 +1452,6 @@ void cfg_show_causes(struct session *); /* format.c */ struct format_tree; -void format_clean(void); struct format_tree *format_create(void); struct format_tree *format_create_status(int); void format_free(struct format_tree *); @@ -1898,6 +1896,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 *); diff --git a/window-choose.c b/window-choose.c index c71fea3d..37baf0d7 100644 --- a/window-choose.c +++ b/window-choose.c @@ -57,7 +57,6 @@ const struct window_mode window_choose_mode = { window_choose_free, window_choose_resize, window_choose_key, - NULL, }; struct window_choose_mode_item { diff --git a/window-clock.c b/window-clock.c index 3cabd9e9..4a497891 100644 --- a/window-clock.c +++ b/window-clock.c @@ -29,8 +29,8 @@ void window_clock_free(struct window_pane *); void window_clock_resize(struct window_pane *, u_int, u_int); void window_clock_key(struct window_pane *, struct client *, struct session *, int, struct mouse_event *); -void window_clock_timer(struct window_pane *); +void window_clock_timer_callback(int, short, void *); void window_clock_draw_screen(struct window_pane *); const struct window_mode window_clock_mode = { @@ -38,12 +38,12 @@ const struct window_mode window_clock_mode = { window_clock_free, window_clock_resize, window_clock_key, - window_clock_timer, }; struct window_clock_mode_data { struct screen screen; time_t tim; + struct event timer; }; const char window_clock_table[14][5][5] = { @@ -119,15 +119,42 @@ const char window_clock_table[14][5][5] = { { 1,0,0,0,1 } }, }; +void +window_clock_timer_callback(unused int fd, unused short events, void *arg) +{ + struct window_pane *wp = arg; + struct window_clock_mode_data *data = wp->modedata; + struct tm now, then; + time_t t; + struct timeval tv = { .tv_sec = 1 }; + + evtimer_del(&data->timer); + evtimer_add(&data->timer, &tv); + + t = time(NULL); + gmtime_r(&t, &now); + gmtime_r(&data->tim, &then); + if (now.tm_min == then.tm_min) + return; + data->tim = t; + + window_clock_draw_screen(wp); + server_redraw_window(wp->window); +} + struct screen * window_clock_init(struct window_pane *wp) { struct window_clock_mode_data *data; struct screen *s; + struct timeval tv = { .tv_sec = 1 }; wp->modedata = data = xmalloc(sizeof *data); data->tim = time(NULL); + evtimer_set(&data->timer, window_clock_timer_callback, wp); + evtimer_add(&data->timer, &tv); + s = &data->screen; screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0); s->mode &= ~MODE_CURSOR; @@ -142,6 +169,7 @@ window_clock_free(struct window_pane *wp) { struct window_clock_mode_data *data = wp->modedata; + evtimer_del(&data->timer); screen_free(&data->screen); free(data); } @@ -164,24 +192,6 @@ window_clock_key(struct window_pane *wp, unused struct client *c, } void -window_clock_timer(struct window_pane *wp) -{ - struct window_clock_mode_data *data = wp->modedata; - struct tm now, then; - time_t t; - - t = time(NULL); - gmtime_r(&t, &now); - gmtime_r(&data->tim, &then); - if (now.tm_min == then.tm_min) - return; - data->tim = t; - - window_clock_draw_screen(wp); - server_redraw_window(wp->window); -} - -void window_clock_draw_screen(struct window_pane *wp) { struct window_clock_mode_data *data = wp->modedata; diff --git a/window-copy.c b/window-copy.c index 7d5bae4c..850b437a 100644 --- a/window-copy.c +++ b/window-copy.c @@ -91,7 +91,6 @@ const struct window_mode window_copy_mode = { window_copy_free, window_copy_resize, window_copy_key, - NULL, }; enum window_copy_input_type { |